/* Built by scripts/build-assets.js from all 54 partials, in styles-new.css order. Do not edit. */

/* base/_variables.css */
/**
 * CSS Variables (Custom Properties)
 * Design tokens for colors, spacing, typography, shadows, etc.
 * 
 * These variables are the foundation of the design system.
 * Update these to change the theme globally.
 */

/* Theme Color Definitions */
:root,
[data-theme="abyssal"],
.theme-abyssal {
    --theme-color-1: #154772;
    --theme-color-2: #031120;
    --theme-color-3: #4DD0E1;
    --theme-color-4: #1FC89B;
    --theme-color-5: #087B74;
    --theme-color-6: #D5F6FF;
}

[data-theme="verdant"],
.theme-verdant {
    --theme-color-1: #2F855A;
    --theme-color-2: #0B1F0A;
    --theme-color-3: #38B2AC;
    --theme-color-4: #F97316;
    --theme-color-5: #4ADE80;
    --theme-color-6: #DCFCE7;
}

[data-theme="solar"],
.theme-solar {
    --theme-color-1: #FACC15;
    --theme-color-2: #451A03;
    --theme-color-3: #F97316;
    --theme-color-4: #F43F5E;
    --theme-color-5: #FDBA74;
    --theme-color-6: #FEF3C7;
}

[data-theme="campfire"],
.theme-campfire {
    --theme-color-1: #3B444B;
    --theme-color-2: #111227;
    --theme-color-3: #FF8A3C;
    --theme-color-4: #FFD166;
    --theme-color-5: #7C0A02;
    --theme-color-6: #F2F3F4;
}

[data-theme="firelands"],
.theme-firelands {
    --theme-color-1: #FF6B35;
    --theme-color-2: #2B1B14;
    --theme-color-3: #FF9F1C;
    --theme-color-4: #FF3A20;
    --theme-color-5: #8C2F1B;
    --theme-color-6: #FFE8D6;
}

[data-theme="nightfall"],
.theme-nightfall {
    --theme-color-1: #2E457D;
    --theme-color-2: #272652;
    --theme-color-3: #82A0B9;
    --theme-color-4: #D7FFF7;
    --theme-color-5: #111227;
    --theme-color-6: #D7FFF7;
}

[data-theme="cherry-blossom"],
.theme-cherry-blossom {
    --theme-color-1: #F472B6;
    --theme-color-2: #2B1A2E;
    --theme-color-3: #FDE68A;
    --theme-color-4: #F9A8D4;
    --theme-color-5: #C08497;
    --theme-color-6: #FFF1F2;
}

[data-theme="putrid-swamp"],
.theme-putrid-swamp {
    --theme-color-1: #718F2D;
    --theme-color-2: #1C2613;
    --theme-color-3: #A3B18A;
    --theme-color-4: #D4A373;
    --theme-color-5: #5B6B2F;
    --theme-color-6: #F0EAD2;
}

[data-theme="crystal-spires"],
.theme-crystal-spires {
    --theme-color-1: #8A4FFF;
    --theme-color-2: #120A3A;
    --theme-color-3: #C3F0FF;
    --theme-color-4: #2DE2E6;
    --theme-color-5: #E4C1F9;
    --theme-color-6: #F8F7FF;
}

[data-theme="stormforged"],
.theme-stormforged {
    --theme-color-1: #4B5563;
    --theme-color-2: #111827;
    --theme-color-3: #A5F3FC;
    --theme-color-4: #B45309;
    --theme-color-5: #EA580C;
    --theme-color-6: #F3F4F6;
}

[data-theme="eldertree"],
.theme-eldertree {
    --theme-color-1: #2E7D32;
    --theme-color-2: #1B3A2F;
    --theme-color-3: #E9C46A;
    --theme-color-4: #F28482;
    --theme-color-5: #8D99AE;
    --theme-color-6: #E9F5E1;
}

[data-theme="frostbound"],
.theme-frostbound {
    --theme-color-1: #7BDFF2;
    --theme-color-2: #0B1D3A;
    --theme-color-3: #A8E6CF;
    --theme-color-4: #FF99C8;
    --theme-color-5: #C7DFF7;
    --theme-color-6: #F0F9FF;
}

[data-theme="sunken-ruins"],
.theme-sunken-ruins {
    --theme-color-1: #1B4965;
    --theme-color-2: #0B1F2B;
    --theme-color-3: #64DFDF;
    --theme-color-4: #133C55;
    --theme-color-5: #B85C38;
    --theme-color-6: #E9D8A6;
}

[data-theme="neon-nexus"],
.theme-neon-nexus {
    --theme-color-1: #FF3CAC;
    --theme-color-2: #050017;
    --theme-color-3: #4CFFEE;
    --theme-color-4: #FFC43D;
    --theme-color-5: #7D3CFF;
    --theme-color-6: #F5F3FF;
}

[data-theme="quantum-void"],
.theme-quantum-void {
    --theme-color-1: #5A0B9A;
    --theme-color-2: #00010A;
    --theme-color-3: #2D9CDB;
    --theme-color-4: #0AFF99;
    --theme-color-5: #FF5F9E;
    --theme-color-6: #C5C6D0;
}

[data-theme="aurora-station"],
.theme-aurora-station {
    --theme-color-1: #1E3A8A;
    --theme-color-2: #020817;
    --theme-color-3: #FFE66D;
    --theme-color-4: #FF7C43;
    --theme-color-5: #1AAE9F;
    --theme-color-6: #E2E8F0;
}

[data-theme="mech-core"],
.theme-mech-core {
    --theme-color-1: #1F2933;
    --theme-color-2: #0B0E14;
    --theme-color-3: #00F5D4;
    --theme-color-4: #8CFF1A;
    --theme-color-5: #FF3860;
    --theme-color-6: #DDE4EB;
}

[data-theme="chromatic-warp"],
.theme-chromatic-warp {
    --theme-color-1: #7F5AF0;
    --theme-color-2: #0F172A;
    --theme-color-3: #FF3B81;
    --theme-color-4: #7CFFCB;
    --theme-color-5: #3A86FF;
    --theme-color-6: #FFF1C7;
}

[data-theme="azure-dunes"],
.theme-azure-dunes {
    --theme-color-1: #D4A574;  /* Warm sand/dune tone */
    --theme-color-2: #1A1F3A;  /* Deep desert night sky */
    --theme-color-3: #87CEEB;  /* Azure blue (sky/oasis) */
    --theme-color-4: #E8956B;  /* Sunset orange accent */
    --theme-color-5: #F4E4C1;  /* Light sand */
    --theme-color-6: #FAF5E9;  /* Lightest sand/parchment */
}

[data-theme="summer-day"],
.theme-summer-day {
    --theme-color-1: #FFB703;
    --theme-color-2: #0D47A1;
    --theme-color-3: #4CAF50;
    --theme-color-4: #FF80AB;
    --theme-color-5: #38BDF8;
    --theme-color-6: #FFF7E6;
}

[data-theme="earth-tones"],
.theme-earth-tones {
    --theme-color-1: #C48A2A;
    --theme-color-2: #3A231A;
    --theme-color-3: #4C6B6E;
    --theme-color-4: #691E23;
    --theme-color-5: #A8947D;  /* Muted terracotta */
    --theme-color-6: #F5EFE6;  /* Light cream */
}

[data-theme="underdark-glow"],
.theme-underdark-glow {
    --theme-color-1: #6A4C93;
    --theme-color-2: #0D0823;
    --theme-color-3: #5FFBF1;
    --theme-color-4: #C77DFF;
    --theme-color-5: #34D399;
    --theme-color-6: #EDE9FE;
}

[data-theme="frost-steel"],
.theme-frost-steel {
    --theme-color-1: #4A5568;  /* Dark steel */
    --theme-color-2: #1A1D29;  /* Deep shadow metal */
    --theme-color-3: #E8F4F8;  /* Bright white snow */
    --theme-color-4: #60A5FA;  /* Sharp ice blue (blade edge) */
    --theme-color-5: #9CA3AF;  /* Cool steel gray */
    --theme-color-6: #FFFFFF;  /* Pure white snow */
}

[data-theme="rusty-armor"],
.theme-rusty-armor {
    --theme-color-1: #B87333;  /* Rust brown */
    --theme-color-2: #2C1810;  /* Dark weathered metal */
    --theme-color-3: #CD853F;  /* Weathered bronze */
    --theme-color-4: #D2691E;  /* Rust orange */
    --theme-color-5: #8B4513;  /* Saddle brown */
    --theme-color-6: #F5DEB3;  /* Wheat */
}

[data-theme="crimson-forest"],
.theme-crimson-forest {
    --theme-color-1: #8B0000;  /* Dark red */
    --theme-color-2: #0D1B0D;  /* Deep forest dark */
    --theme-color-3: #DC143C;  /* Crimson */
    --theme-color-4: #2D5016;  /* Dark forest green */
    --theme-color-5: #6B4423;  /* Dark wood brown */
    --theme-color-6: #F5E6D3;  /* Pale parchment */
}

[data-theme="twilight"],
.theme-twilight {
    --theme-color-1: #4B0082;  /* Indigo */
    --theme-color-2: #1A1A2E;  /* Deep twilight sky */
    --theme-color-3: #FF6B9D;  /* Soft pink */
    --theme-color-4: #FF8C42;  /* Sunset orange */
    --theme-color-5: #9370DB;  /* Medium purple */
    --theme-color-6: #E6E6FA;  /* Lavender */
}

/* Soft variants: quiet surfaces, luminous accents. Original palettes stay unchanged. */
[data-theme="abyssal-soft"],
.theme-abyssal-soft {
    --theme-color-1: #233947;
    --theme-color-2: #0C1A25;
    --theme-color-3: #8ABFC7;
    --theme-color-4: #8BCDB8;
    --theme-color-5: #A9D0D6;
    --theme-color-6: #E2EFF1;
}

[data-theme="verdant-soft"],
.theme-verdant-soft {
    --theme-color-1: #263E34;
    --theme-color-2: #111E18;
    --theme-color-3: #94C7AF;
    --theme-color-4: #D6AB83;
    --theme-color-5: #B1D5C2;
    --theme-color-6: #E7F0E5;
}

[data-theme="solar-soft"],
.theme-solar-soft {
    --theme-color-1: #48362A;
    --theme-color-2: #251B15;
    --theme-color-3: #E4BF82;
    --theme-color-4: #DDA18D;
    --theme-color-5: #EBCFA3;
    --theme-color-6: #F7EEE0;
}

[data-theme="campfire-soft"],
.theme-campfire-soft {
    --theme-color-1: #343440;
    --theme-color-2: #181923;
    --theme-color-3: #D6AA83;
    --theme-color-4: #DCC69A;
    --theme-color-5: #E0C0A4;
    --theme-color-6: #F3EAE2;
}

[data-theme="firelands-soft"],
.theme-firelands-soft {
    --theme-color-1: #46322E;
    --theme-color-2: #231816;
    --theme-color-3: #E2AA8E;
    --theme-color-4: #D8BE89;
    --theme-color-5: #E9C1AB;
    --theme-color-6: #F7EBE1;
}

[data-theme="cherry-blossom-soft"],
.theme-cherry-blossom-soft {
    --theme-color-1: #443342;
    --theme-color-2: #211921;
    --theme-color-3: #D8ADC5;
    --theme-color-4: #E4CFAB;
    --theme-color-5: #E3C3D4;
    --theme-color-6: #F6ECF1;
}

[data-theme="putrid-swamp-soft"],
.theme-putrid-swamp-soft {
    --theme-color-1: #2B382C;
    --theme-color-2: #161F1B;
    --theme-color-3: #A3B18A;
    --theme-color-4: #C4B186;
    --theme-color-5: #BEC5A3;
    --theme-color-6: #F0EAD2;
}

[data-theme="nightfall-soft"],
.theme-nightfall-soft {
    --theme-color-1: #30394C;
    --theme-color-2: #171D2A;
    --theme-color-3: #A4B8D5;
    --theme-color-4: #C3B6D5;
    --theme-color-5: #BDCCE1;
    --theme-color-6: #EAF0F7;
}

[data-theme="crystal-spires-soft"],
.theme-crystal-spires-soft {
    --theme-color-1: #39334A;
    --theme-color-2: #1C1828;
    --theme-color-3: #C4B5DB;
    --theme-color-4: #A8CED5;
    --theme-color-5: #D3C8E5;
    --theme-color-6: #F0ECF7;
}

[data-theme="stormforged-soft"],
.theme-stormforged-soft {
    --theme-color-1: #343E47;
    --theme-color-2: #191F26;
    --theme-color-3: #ACBCC8;
    --theme-color-4: #DBAA82;
    --theme-color-5: #C2CED7;
    --theme-color-6: #EAF0F2;
}

[data-theme="eldertree-soft"],
.theme-eldertree-soft {
    --theme-color-1: #304737;
    --theme-color-2: #17261F;
    --theme-color-3: #CFBC85;
    --theme-color-4: #A9C998;
    --theme-color-5: #D8CEA5;
    --theme-color-6: #E9F0DF;
}

[data-theme="frostbound-soft"],
.theme-frostbound-soft {
    --theme-color-1: #2E414A;
    --theme-color-2: #152129;
    --theme-color-3: #ACCEDB;
    --theme-color-4: #B7D5C4;
    --theme-color-5: #C3DCE4;
    --theme-color-6: #EDF5F6;
}

[data-theme="sunken-ruins-soft"],
.theme-sunken-ruins-soft {
    --theme-color-1: #29413F;
    --theme-color-2: #132322;
    --theme-color-3: #95C7C0;
    --theme-color-4: #DBAA9B;
    --theme-color-5: #B1D6D0;
    --theme-color-6: #E5F1ED;
}

[data-theme="neon-nexus-soft"],
.theme-neon-nexus-soft {
    --theme-color-1: #3A2C46;
    --theme-color-2: #1D1527;
    --theme-color-3: #D2A1CD;
    --theme-color-4: #91D2CB;
    --theme-color-5: #DEBBDB;
    --theme-color-6: #F3EAF6;
}

[data-theme="quantum-void-soft"],
.theme-quantum-void-soft {
    --theme-color-1: #302D48;
    --theme-color-2: #171527;
    --theme-color-3: #B5AFE1;
    --theme-color-4: #99CDCF;
    --theme-color-5: #C8C4E9;
    --theme-color-6: #ECEBF7;
}

[data-theme="aurora-station-soft"],
.theme-aurora-station-soft {
    --theme-color-1: #2D3A48;
    --theme-color-2: #151E28;
    --theme-color-3: #A3C6DC;
    --theme-color-4: #D8B694;
    --theme-color-5: #BCD5E5;
    --theme-color-6: #EAF1F6;
}

[data-theme="mech-core-soft"],
.theme-mech-core-soft {
    --theme-color-1: #303F3D;
    --theme-color-2: #17211F;
    --theme-color-3: #A6C9BE;
    --theme-color-4: #C4D09C;
    --theme-color-5: #BFD8CD;
    --theme-color-6: #EDF3E9;
}

[data-theme="chromatic-warp-soft"],
.theme-chromatic-warp-soft {
    --theme-color-1: #3C3049;
    --theme-color-2: #1C1728;
    --theme-color-3: #C4ACDD;
    --theme-color-4: #9FD1D4;
    --theme-color-5: #D4C2E6;
    --theme-color-6: #F1ECF7;
}

[data-theme="azure-dunes-soft"],
.theme-azure-dunes-soft {
    --theme-color-1: #394149;
    --theme-color-2: #1D2227;
    --theme-color-3: #A7CAD8;
    --theme-color-4: #DCC299;
    --theme-color-5: #C2D7DD;
    --theme-color-6: #F3F0E6;
}

[data-theme="summer-day-soft"],
.theme-summer-day-soft {
    --theme-color-1: #384A49;
    --theme-color-2: #1B2728;
    --theme-color-3: #ADD6D9;
    --theme-color-4: #E9CC8E;
    --theme-color-5: #C7E1DE;
    --theme-color-6: #F8F4E7;
}

[data-theme="earth-tones-soft"],
.theme-earth-tones-soft {
    --theme-color-1: #40362C;
    --theme-color-2: #251F1B;
    --theme-color-3: #C7AD7C;
    --theme-color-4: #ACBCA7;
    --theme-color-5: #D7C4A1;
    --theme-color-6: #F5EFE6;
}

[data-theme="underdark-glow-soft"],
.theme-underdark-glow-soft {
    --theme-color-1: #343449;
    --theme-color-2: #171827;
    --theme-color-3: #B9B0D5;
    --theme-color-4: #92CDBD;
    --theme-color-5: #CBC5E1;
    --theme-color-6: #EDEBF6;
}

[data-theme="frost-steel-soft"],
.theme-frost-steel-soft {
    --theme-color-1: #323D48;
    --theme-color-2: #1A1F27;
    --theme-color-3: #A4BDCF;
    --theme-color-4: #C0CCD4;
    --theme-color-5: #BECFDB;
    --theme-color-6: #EDF0F2;
}

[data-theme="rusty-armor-soft"],
.theme-rusty-armor-soft {
    --theme-color-1: #43382F;
    --theme-color-2: #231D18;
    --theme-color-3: #CDAE8C;
    --theme-color-4: #BBA482;
    --theme-color-5: #DAC3A9;
    --theme-color-6: #F2EAE0;
}

[data-theme="crimson-forest-soft"],
.theme-crimson-forest-soft {
    --theme-color-1: #403331;
    --theme-color-2: #1C201A;
    --theme-color-3: #D6A19F;
    --theme-color-4: #B6C19A;
    --theme-color-5: #E0BBB5;
    --theme-color-6: #F3EBDD;
}

[data-theme="twilight-soft"],
.theme-twilight-soft {
    --theme-color-1: #3E334A;
    --theme-color-2: #1E1A29;
    --theme-color-3: #D4ACCE;
    --theme-color-4: #D8B095;
    --theme-color-5: #DEC2DC;
    --theme-color-6: #F1ECF7;
}

[data-theme="gloamlight-soft"],
.theme-gloamlight-soft {
    --theme-color-1: #20302D;
    --theme-color-2: #121C1C;
    --theme-color-3: #9BC8B4;
    --theme-color-4: #C5C6A0;
    --theme-color-5: #B8D4C3;
    --theme-color-6: #EEEAE0;
}

/* Theme Transition Smoothing */
:root.theme-transitioning,
:root.theme-transitioning *,
.modal.theme-transitioning,
.modal.theme-transitioning *,
.window.theme-transitioning,
.window.theme-transitioning * {
    transition: background-color 0.3s ease, 
                color 0.3s ease, 
                border-color 0.3s ease !important;
}

/* Root Variables - Semantic Color System */
:root {
    /* Abyssal Theme Aliases */
    --abyssal-purple: var(--theme-color-1);
    --abyssal-dark: var(--theme-color-2);
    --abyssal-glow: var(--theme-color-3);
    --abyssal-accent: var(--theme-color-4);
    --abyssal-teal: var(--theme-color-5);
    --abyssal-light: var(--theme-color-6);
    --abyssal-gray: color-mix(in srgb, var(--theme-color-1) 35%, var(--theme-color-2) 65%);

    /* Primary Color System */
    --primary-color: var(--abyssal-glow);
    --secondary-color: var(--abyssal-teal);
    --accent-color: var(--abyssal-accent);
    --highlight-color: var(--abyssal-purple);
    
    /* Background Colors */
    --bg-dark: var(--abyssal-dark);
    --bg-light: color-mix(in srgb, var(--theme-color-6) 70%, var(--theme-color-1) 30%);
    
    /* Text Colors */
    --text-light: var(--abyssal-light);
    --text-dim: color-mix(in srgb, var(--text-light) 70%, var(--theme-color-3) 30%);
    
    /* Border Colors */
    --border-color: color-mix(in srgb, var(--primary-color) 35%, transparent);
    
    /* How wide the content column is allowed to get.
       The application bar is fixed to the top of the window, outside whatever
       container the page uses, so it has no way of knowing how wide that
       container is — it carried its own hard-coded 1400px and the store's
       pages capped at 1200, which put the nav links outside the edge of the
       content they sit above on any wide screen.
       Pages that want a different column set this on their own body class and
       the bar follows, because a custom property inherits. */
    --page-max: 1200px;

    /* Surface/Panel Colors */
    --surface-base: color-mix(in srgb, var(--theme-color-2) 90%, black 10%);
    --surface-panel: color-mix(in srgb, var(--theme-color-1) 60%, var(--surface-base) 40%);
    --surface-overlay: color-mix(in srgb, var(--theme-color-1) 35%, transparent 65%);
    --surface-glow: color-mix(in srgb, var(--accent-color) 40%, var(--theme-color-6) 60%);
    
    /* Shadow Colors */
    --shadow-color: color-mix(in srgb, black 65%, var(--theme-color-2) 35%);
    
    /* Panel Opacity Variants */
    --panel-98: color-mix(in srgb, var(--surface-base) 95%, transparent 5%);
    --panel-90: color-mix(in srgb, var(--surface-base) 90%, transparent 10%);
    --panel-75: color-mix(in srgb, var(--surface-base) 75%, transparent 25%);
    --panel-60: color-mix(in srgb, var(--surface-base) 60%, transparent 40%);
    --panel-40: color-mix(in srgb, var(--surface-panel) 40%, transparent 60%);
    
    /* Accent Opacity Variants */
    --accent-primary-20: color-mix(in srgb, var(--primary-color) 20%, transparent 80%);
    --accent-primary-35: color-mix(in srgb, var(--primary-color) 35%, transparent 65%);
    --accent-secondary-20: color-mix(in srgb, var(--secondary-color) 20%, transparent 80%);
    --accent-secondary-35: color-mix(in srgb, var(--secondary-color) 35%, transparent 65%);
    --accent-accent-20: color-mix(in srgb, var(--accent-color) 20%, transparent 80%);
    --accent-accent-35: color-mix(in srgb, var(--accent-color) 35%, transparent 65%);
    
    /* Glass Effects */
    --glass-90: color-mix(in srgb, var(--surface-panel) 90%, transparent 10%);
    --glass-80: color-mix(in srgb, var(--surface-panel) 80%, transparent 20%);
    --glass-70: color-mix(in srgb, var(--surface-panel) 70%, transparent 30%);
    --glass-60: color-mix(in srgb, var(--surface-panel) 60%, transparent 40%);
    
    /* Outline Variants */
    --outline-soft: color-mix(in srgb, var(--primary-color) 25%, transparent);
    --outline-strong: color-mix(in srgb, var(--primary-color) 45%, transparent);
    
    /* Shadow Variants */
    --shadow-primary-25: color-mix(in srgb, var(--primary-color) 25%, transparent);
    --shadow-primary-35: color-mix(in srgb, var(--primary-color) 35%, transparent);
    --shadow-primary-50: color-mix(in srgb, var(--primary-color) 50%, transparent);
    --shadow-accent-35: color-mix(in srgb, var(--accent-color) 35%, transparent);
    --shadow-ambient-30: color-mix(in srgb, var(--shadow-color) 30%, transparent);
    --shadow-ambient-40: color-mix(in srgb, var(--shadow-color) 40%, transparent);
    --shadow-ambient-55: color-mix(in srgb, var(--shadow-color) 55%, transparent);
    
    /* Category Colors (for items, etc.) */
    --category-weapon: var(--secondary-color);
    --category-armor: color-mix(in srgb, var(--accent-color) 80%, var(--primary-color) 20%);
    --category-consumable: color-mix(in srgb, var(--secondary-color) 65%, var(--accent-color) 35%);
    --category-tool: var(--primary-color);
    --category-misc: var(--text-light);
    --category-weapon-bg: color-mix(in srgb, var(--category-weapon) 20%, transparent);
    --category-armor-bg: color-mix(in srgb, var(--category-armor) 20%, transparent);
    --category-consumable-bg: color-mix(in srgb, var(--category-consumable) 20%, transparent);
    --category-tool-bg: color-mix(in srgb, var(--category-tool) 20%, transparent);
    --category-misc-bg: color-mix(in srgb, var(--surface-panel) 20%, transparent);
    
    /* Semantic Colors */
    /* Danger has to look like danger, and it does NOT get themed.
       This was `var(--accent-color)` — the palette's own highlight — so the
       colour meaning "this destroys something" was green in abyssal, yellow in
       campfire, pink in cherry-blossom. A checkout error rendered in success
       green is what turned this up; every btn-danger and every delete control
       in the app had the same problem, 71 usages of it.
       One fixed red, deliberately not mixed with anything: a warning that
       changes colour with the decor is a warning you have to learn 26 times.
       #ff9a9a is soft enough to sit in these palettes and still clears AA on
       every one of them — the worst, summer-day, lands at 4.80:1. Anything
       redder fails there: #ff8080 is 4.02. test/theme-contrast.test.js holds
       both halves of that. */
    --danger-color: #ff9a9a;
    --danger-bg-20: color-mix(in srgb, var(--danger-color) 20%, transparent);
    --danger-bg-35: color-mix(in srgb, var(--danger-color) 35%, transparent);
    --success-color: var(--secondary-color);
    --success-bg-20: color-mix(in srgb, var(--success-color) 20%, transparent);
    --neutral-bg-20: color-mix(in srgb, var(--primary-color) 20%, transparent);
    --neutral-bg-35: color-mix(in srgb, var(--primary-color) 35%, transparent);
}


/* base/_reset.css */
/**
 * CSS Reset
 * Normalizes browser default styles for consistent rendering
 */

* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}


/* base/_typography.css */
/**
 * Typography
 * Base typography styles and text utilities
 */

body {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background: linear-gradient(135deg, var(--abyssal-dark) 0%, var(--abyssal-purple) 100%);
    background-attachment: fixed;
    color: var(--text-light, #E0E7FF);
    min-height: 100vh;
    padding: 20px;
    position: relative;
}

/* Apply sidebar padding when sidebar-nav is present */
body:has(.sidebar-nav):not(.no-sidebar) {
    padding-top: calc(40px + 20px);
    padding-left: calc(56px + 40px);
    transition: padding-left 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

/* Adjust padding when sidebar is expanded */
body:has(.sidebar-nav:hover):not(.no-sidebar) {
    padding-left: calc(220px + 40px);
}

/* Text Utilities */
.is-hidden {
    display: none !important;
}

.text-center {
    text-align: center;
}

.text-left {
    text-align: left;
}

.text-right {
    text-align: right;
}

.text-muted {
    color: var(--text-dim);
    opacity: 0.8;
}

.text-primary {
    color: var(--primary-color);
}

.text-accent {
    color: var(--accent-color);
}

.text-secondary {
    color: var(--secondary-color);
}


/* themes/_animations.css */
/**
 * Animations and Keyframes
 * All keyframe animations used throughout the application
 */

/* Fade Animations */
@keyframes fadeIn {
    0% {
        opacity: 0;
    }
    100% {
        opacity: 1;
    }
}

@keyframes fadeInUp {
    0% {
        opacity: 0;
        transform: translateY(10px);
    }
    100% {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes fadeInScale {
    0% {
        opacity: 0;
        transform: scale(0.95);
    }
    100% {
        opacity: 1;
        transform: scale(1);
    }
}

/* Logo Animations - Reduced intensity for smoother performance */
@keyframes logoFloat {
    0%, 100% {
        transform: translateY(0px);
    }
    50% {
        transform: translateY(-5px);
    }
}

@keyframes logoGlow {
    0%, 100% {
        filter: drop-shadow(0 0 20px color-mix(in srgb, var(--primary-color) 60%, transparent));
    }
    50% {
        filter: drop-shadow(0 0 30px color-mix(in srgb, var(--primary-color) 75%, transparent));
    }
}

/* Rune Icon Animations */
@keyframes rune-pulse {
    0%, 100% {
        filter: drop-shadow(0 0 3px currentColor);
    }
    50% {
        filter: drop-shadow(0 0 8px currentColor);
    }
}

.rune-icon-pulse {
    animation: rune-pulse 2s ease-in-out infinite;
}

/* Badge and Highlight Animations */
@keyframes pulse-badge {
    0%, 100% {
        transform: scale(1);
        box-shadow: 0 0 0 0 rgba(236, 72, 153, 0.7);
    }
    50% {
        transform: scale(1.05);
        box-shadow: 0 0 0 4px rgba(236, 72, 153, 0);
    }
}

@keyframes highlight-pulse {
    0%, 100% {
        background: rgba(236, 72, 153, 0.1);
    }
    50% {
        background: rgba(236, 72, 153, 0.2);
    }
}

@keyframes glow-pulse {
    0%, 100% {
        opacity: 1;
        box-shadow: 0 0 5px rgba(236, 72, 153, 0.5);
    }
    50% {
        opacity: 0.8;
        box-shadow: 0 0 10px rgba(236, 72, 153, 0.8);
    }
}

/* Slide Animations */
@keyframes slideInRight {
    from {
        transform: translateX(100%);
        opacity: 0;
    }
    to {
        transform: translateX(0);
        opacity: 1;
    }
}

@keyframes slideOutRight {
    from {
        transform: translateX(0);
        opacity: 1;
    }
    to {
        transform: translateX(100%);
        opacity: 0;
    }
}

@keyframes slideInFromTop {
    from {
        transform: translateY(-100%);
        opacity: 0;
    }
    to {
        transform: translateY(0);
        opacity: 1;
    }
}

@keyframes slideInFromBottom {
    from {
        transform: translateY(100px);
        opacity: 0;
    }
    to {
        transform: translateY(0);
        opacity: 1;
    }
}

/* Window Animations */
@keyframes windowAppear {
    from {
        opacity: 0;
        transform: scale(0.8) translateY(-20px);
    }
    to {
        opacity: 1;
        transform: scale(1) translateY(0);
    }
}

@keyframes windowMinimize {
    from {
        opacity: 1;
        transform: scale(1);
    }
    to {
        opacity: 0.5;
        transform: scale(0.95);
    }
}

@keyframes windowRestore {
    from {
        opacity: 0.5;
        transform: scale(0.95);
    }
    to {
        opacity: 1;
        transform: scale(1);
    }
}

/* Dice Roll Animations */
@keyframes rollAppear {
    from {
        transform: translateX(20px);
        opacity: 0;
    }
    to {
        transform: translateX(0);
        opacity: 1;
    }
}

@keyframes bubbleFloat {
    0%, 100% {
        transform: translateY(0);
    }
    50% {
        transform: translateY(-8px);
    }
}

@keyframes bubbleExpand {
    from {
        transform: scale(0.8);
        opacity: 0;
    }
    to {
        transform: scale(1);
        opacity: 1;
    }
}


/* themes/_body-backgrounds.css */
/**
 * Theme Body Backgrounds
 * Background gradients for each theme applied to body element
 */

/* Swap Tonal Theme Helpers */
body[data-theme="verdant"],
.theme-verdant body {
    background: linear-gradient(135deg, var(--theme-color-2, #0B1F0A) 0%, var(--theme-color-1, #2F855A) 100%);
}

body[data-theme="solar"],
.theme-solar body {
    background: linear-gradient(135deg, var(--theme-color-2, #451A03) 0%, var(--theme-color-1, #FACC15) 100%);
}

body[data-theme="firelands"],
.theme-firelands body {
    background: linear-gradient(135deg, var(--theme-color-2, #2B1B14) 0%, color-mix(in srgb, var(--theme-color-4, #FF3A20) 65%, var(--theme-color-3, #FF9F1C) 35%) 55%, var(--theme-color-1, #FF6B35) 100%);
}

body[data-theme="cherry-blossom"],
.theme-cherry-blossom body {
    background: linear-gradient(135deg, var(--theme-color-2, #2B1A2E) 0%, color-mix(in srgb, var(--theme-color-4, #F9A8D4) 70%, var(--theme-color-6, #FFF1F2) 30%) 55%, var(--theme-color-1, #F472B6) 100%);
}

body[data-theme="putrid-swamp"],
.theme-putrid-swamp body {
    background: linear-gradient(135deg, var(--theme-color-2, #1C2613) 0%, color-mix(in srgb, var(--theme-color-5, #5B6B2F) 60%, var(--theme-color-3, #A3B18A) 40%) 55%, var(--theme-color-1, #718F2D) 100%);
}

body[data-theme="crystal-spires"],
.theme-crystal-spires body {
    background: linear-gradient(135deg, var(--theme-color-2, #120A3A) 0%, color-mix(in srgb, var(--theme-color-4, #2DE2E6) 65%, var(--theme-color-3, #C3F0FF) 35%) 55%, var(--theme-color-1, #8A4FFF) 100%);
}

body[data-theme="stormforged"],
.theme-stormforged body {
    background: linear-gradient(135deg, var(--theme-color-2, #111827) 0%, color-mix(in srgb, var(--theme-color-5, #EA580C) 55%, var(--theme-color-4, #B45309) 45%) 55%, var(--theme-color-1, #4B5563) 100%);
}

body[data-theme="eldertree"],
.theme-eldertree body {
    background: linear-gradient(135deg, var(--theme-color-2, #1B3A2F) 0%, color-mix(in srgb, var(--theme-color-3, #E9C46A) 60%, var(--theme-color-4, #F28482) 40%) 55%, var(--theme-color-1, #2E7D32) 100%);
}

body[data-theme="frostbound"],
.theme-frostbound body {
    background: linear-gradient(135deg, var(--theme-color-2, #0B1D3A) 0%, color-mix(in srgb, var(--theme-color-5, #C7DFF7) 55%, var(--theme-color-3, #A8E6CF) 45%) 55%, var(--theme-color-1, #7BDFF2) 100%);
}

body[data-theme="sunken-ruins"],
.theme-sunken-ruins body {
    background: linear-gradient(135deg, var(--theme-color-2, #0B1F2B) 0%, color-mix(in srgb, var(--theme-color-4, #133C55) 60%, var(--theme-color-3, #64DFDF) 40%) 55%, var(--theme-color-1, #1B4965) 100%);
}

body[data-theme="neon-nexus"],
.theme-neon-nexus body {
    background: linear-gradient(135deg, var(--theme-color-2, #050017) 0%, color-mix(in srgb, var(--theme-color-5, #7D3CFF) 60%, var(--theme-color-3, #4CFFEE) 40%) 55%, var(--theme-color-1, #FF3CAC) 100%);
}

body[data-theme="quantum-void"],
.theme-quantum-void body {
    background: linear-gradient(135deg, var(--theme-color-2, #00010A) 0%, color-mix(in srgb, var(--theme-color-3, #2D9CDB) 55%, var(--theme-color-4, #0AFF99) 45%) 55%, var(--theme-color-1, #5A0B9A) 100%);
}

body[data-theme="aurora-station"],
.theme-aurora-station body {
    background: linear-gradient(135deg, var(--theme-color-2, #020817) 0%, color-mix(in srgb, var(--theme-color-5, #1AAE9F) 55%, var(--theme-color-3, #FFE66D) 45%) 55%, var(--theme-color-1, #1E3A8A) 100%);
}

body[data-theme="mech-core"],
.theme-mech-core body {
    background: linear-gradient(135deg, var(--theme-color-2, #0B0E14) 0%, color-mix(in srgb, var(--theme-color-4, #8CFF1A) 55%, var(--theme-color-3, #00F5D4) 45%) 55%, var(--theme-color-1, #1F2933) 100%);
}

body[data-theme="chromatic-warp"],
.theme-chromatic-warp body {
    background: linear-gradient(135deg, var(--theme-color-2, #0F172A) 0%, color-mix(in srgb, var(--theme-color-4, #7CFFCB) 60%, var(--theme-color-3, #FF3B81) 40%) 55%, var(--theme-color-1, #7F5AF0) 100%);
}

body[data-theme="azure-dunes"],
.theme-azure-dunes body {
    background: linear-gradient(135deg, var(--theme-color-2, #3A1F0B) 0%, color-mix(in srgb, var(--theme-color-5, #C47335) 55%, var(--theme-color-3, #87CEEB) 45%) 55%, var(--theme-color-1, #E4A672) 100%);
}

body[data-theme="summer-day"],
.theme-summer-day body {
    background: linear-gradient(135deg, var(--theme-color-2, #0D47A1) 0%, color-mix(in srgb, var(--theme-color-5, #38BDF8) 55%, var(--theme-color-3, #4CAF50) 45%) 55%, var(--theme-color-1, #FFB703) 100%);
}

body[data-theme="underdark-glow"],
.theme-underdark-glow body {
    background: linear-gradient(135deg, var(--theme-color-2, #0D0823) 0%, color-mix(in srgb, var(--theme-color-4, #C77DFF) 60%, var(--theme-color-3, #5FFBF1) 40%) 55%, var(--theme-color-1, #6A4C93) 100%);
}


/* layout/_navigation.css */
/**
 * Navigation Components
 * Top navigation bar and related components
 */

.top-nav-bar {
    background: linear-gradient(
        135deg,
        color-mix(in srgb, var(--surface-base) 80%, transparent 20%) 0%,
        color-mix(in srgb, var(--surface-panel) 85%, transparent 15%) 100%
    );
    backdrop-filter: blur(10px);
    border-bottom: 1px solid color-mix(in srgb, var(--secondary-color) 30%, transparent);
    padding: 8px 16px;
    padding-left: calc(56px + 20px + 16px); /* Account for sidebar + padding - IDE style */
    padding-right: 20px; /* Right padding to balance - IDE style */
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 12px;
    flex-wrap: nowrap;
    position: sticky;
    top: 40px; /* Below top banner - IDE style */
    z-index: 100;
    box-shadow: 0 2px 10px var(--shadow-ambient-30);
    transition: padding-left 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

/* Combat tracker page top-nav-bar - right justified and no top banner above */
.characters-page .top-nav-bar {
    justify-content: flex-end; /* Right justify for combat tracker */
    top: 0; /* No top banner, so start at top */
    position: relative; /* Change from sticky to relative for proper centering */
    padding-left: 0 !important; /* No sidebar padding - centered */
    padding-right: 0 !important; /* No right padding - centered */
    max-width: 1800px; /* Match content max-width */
    margin: 0 auto; /* Center the nav bar */
    box-sizing: border-box;
    width: 100%; /* Full width for centering */
}

/* Combat tracker top-nav-bar should never have sidebar padding */
body:has(.sidebar-nav.is-expanded) .characters-page .top-nav-bar {
    padding-left: 0 !important; /* NO sidebar padding - always centered */
}

/* The expanded drawer overlays the workspace without moving its content. */

.top-nav-title {
    display: flex;
    align-items: center;
    gap: 10px;
    font-size: 1.2em;
    font-weight: 600;
    color: var(--primary-color);
    flex-shrink: 0;
}

.top-nav-search {
    flex: 1;
    min-width: 0;
    max-width: 400px;
}

.top-nav-search input {
    width: 100%;
    padding: 8px 12px;
    background: color-mix(in srgb, var(--surface-panel) 70%, transparent 30%);
    border: 1px solid color-mix(in srgb, var(--border-color) 50%, transparent);
    border-radius: 6px;
    color: var(--text-light);
    font-size: 0.9em;
    transition: all 0.2s ease;
}

.top-nav-search input:focus {
    outline: none;
    border-color: var(--primary-color);
    background: color-mix(in srgb, var(--surface-panel) 85%, transparent 15%);
    box-shadow: 0 0 10px color-mix(in srgb, var(--primary-color) 20%, transparent);
}

.top-nav-actions {
    display: flex;
    gap: 8px;
    align-items: center;
    flex-shrink: 0;
}

.top-nav-filter {
    display: flex;
    align-items: center;
    gap: 8px;
}

.top-nav-filter select {
    padding: 6px 12px;
    background: color-mix(in srgb, var(--surface-panel) 70%, transparent 30%);
    border: 1px solid color-mix(in srgb, var(--border-color) 50%, transparent);
    border-radius: 6px;
    color: var(--text-light);
    font-size: 0.85em;
    cursor: pointer;
    transition: all 0.2s ease;
}

.top-nav-filter select:focus {
    outline: none;
    border-color: var(--primary-color);
    background: color-mix(in srgb, var(--surface-panel) 85%, transparent 15%);
}

/* Header (deprecated but kept for backward compatibility) */
.header {
    text-align: center;
    margin-bottom: 40px;
    padding: 30px 20px;
    background: color-mix(in srgb, var(--surface-panel) 85%, transparent 15%);
    border: 2px solid var(--border-color);
    border-radius: 16px;
    backdrop-filter: blur(10px);
}

.logo-container {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 30px;
    margin-bottom: 15px;
}

.logo-container .main-logo {
    max-height: 100px;
    height: auto;
    width: auto;
    max-width: 300px;
    filter: drop-shadow(0 0 20px rgba(168, 85, 247, 0.8));
    transition: all 0.3s ease;
}

.logo-container .main-logo:hover {
    filter: drop-shadow(0 0 30px rgba(168, 85, 247, 1));
    transform: scale(1.05);
}

.header-text {
    display: flex;
    flex-direction: column;
    gap: 5px;
}

.header h1 {
    font-size: 3em;
    color: var(--primary-color);
    margin-bottom: 10px;
}

.subtitle {
    font-size: 1.2em;
    color: var(--text-dim);
    font-weight: 300;
}

/* Footer */
.footer {
    text-align: center;
    padding: 30px 20px;
    color: var(--text-dim);
    font-size: 0.9em;
    border-top: 1px solid var(--border-color);
    margin-top: 60px;
}

/* Scrollbar Styling */
::-webkit-scrollbar {
    width: 10px;
}

::-webkit-scrollbar-track {
    background: color-mix(in srgb, var(--theme-color-2, var(--abyssal-dark)) 50%, transparent);
    border-radius: 5px;
}

::-webkit-scrollbar-thumb {
    background: color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 60%, transparent);
    border-radius: 5px;
}

::-webkit-scrollbar-thumb:hover {
    background: color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 90%, transparent);
}

/* Top Banner - spans full width including over sidebar */
.top-banner {
    position: fixed;
    top: 0;
    left: 0; /* Start from very left - spans over sidebar */
    right: 0;
    width: 100vw; /* Full viewport width */
    height: 40px;
    background: color-mix(in srgb, var(--panel-75) 95%, transparent 5%);
    border-bottom: 2px solid color-mix(in srgb, var(--primary-color) 40%, transparent);
    z-index: 10001; /* Above sidebar which is 9999 */
    display: flex;
    align-items: center;
    padding: 0 20px;
    box-shadow: 0 2px 8px var(--shadow-ambient-30);
    backdrop-filter: blur(10px);
}

/* Hide top banner on combat tracker page (characters-page with top-nav-bar) */
.characters-page:has(.top-nav-bar) .top-banner {
    display: none !important;
}

.banner-content {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 20px;
    position: relative;
}

.banner-user-info {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-right: 12px;
}

.banner-username {
    color: var(--primary-color);
    font-weight: 500;
    font-size: 0.8em;
    text-transform: capitalize;
}

.banner-user-status {
    color: var(--text-light);
    font-weight: 400;
    font-size: 0.75em;
    opacity: 0.8;
    text-transform: capitalize;
}

.banner-left-actions {
    display: flex;
    align-items: center;
    gap: 6px;
    position: absolute;
    left: 12px; /* Position at far left, over sidebar */
    justify-content: flex-start;
    z-index: 10002; /* Above banner background */
}

.banner-actions {
    display: flex;
    align-items: center;
    gap: 6px;
    justify-content: flex-end;
    position: absolute;
    right: 16px;
}

/* Banner Button Styles */
.banner-btn {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    padding: 3px 6px;
    background: color-mix(in srgb, var(--primary-color) 15%, transparent);
    border: 1px solid color-mix(in srgb, var(--primary-color) 40%, transparent);
    border-radius: 8px;
    color: var(--primary-color);
    font-size: 0.875em;
    font-weight: 500;
    cursor: pointer;
    transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
    text-align: left;
    white-space: nowrap;
    height: 28px;
    text-decoration: none;
    position: relative;
}

/* Removed full-width line effect - was causing visual issues */

.banner-btn:hover {
    background: color-mix(in srgb, var(--primary-color) 25%, transparent);
    transform: translateY(-1px);
    box-shadow: 0 2px 8px color-mix(in srgb, var(--primary-color) 30%, transparent);
}

.banner-btn:active {
    transform: translateY(0);
    background: color-mix(in srgb, var(--primary-color) 20%, transparent);
}

.banner-btn.active {
    background: color-mix(in srgb, var(--primary-color) 20%, transparent);
    color: var(--accent-color);
    border: 1px solid var(--primary-color);
}

.banner-btn.active:hover {
    background: color-mix(in srgb, var(--primary-color) 30%, transparent);
}

.banner-btn .rune-icon {
    width: 14px;
    height: 14px;
    margin-right: 6px;
}

/* Sidebar Navigation */
.sidebar-nav {
    position: fixed;
    left: 0;
    top: var(--navigation-top, 40px);
    height: calc(100dvh - var(--navigation-top, 40px));
    width: 56px; /* Collapsed width - IDE style */
    background: color-mix(in srgb, var(--surface-base) 70%, var(--accent-color) 30%);
    border-right: 1px solid color-mix(in srgb, var(--primary-color) 40%, transparent);
    backdrop-filter: blur(20px);
    box-shadow: 2px 0 12px color-mix(in srgb, var(--shadow-color) 25%, var(--accent-color) 10%);
    z-index: 9999;
    transition: width 0.25s cubic-bezier(0.4, 0, 0.2, 1);
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

.sidebar-nav.is-expanded {
    width: min(280px, calc(100vw - 24px));
}

.sidebar-menu-toggle {
    display: flex;
    align-items: center;
    gap: 12px;
    flex: 0 0 52px;
    width: 100%;
    padding: 12px 16px;
    border: 0;
    border-bottom: 1px solid var(--border-color);
    background: transparent;
    color: var(--text-light, #edf0ef);
    font: inherit;
    cursor: pointer;
    text-align: left;
}

.sidebar-menu-toggle svg { width: 22px; height: 22px; flex-shrink: 0; }
.sidebar-navigation-content { overflow-y: auto; overflow-x: hidden; min-height: 0; flex: 1; }
.sidebar-nav .navigation-icon { width: 22px; height: 22px; color: #b8d9d5; flex-shrink: 0; }
.sidebar-nav-header { flex-shrink: 0; }
.sidebar-nav:not(.is-expanded) .sidebar-nav-header,
.sidebar-nav:not(.is-expanded) #shared-users-container { display: none; }
.sidebar-nav .sidebar-logo { display: none; }
.sidebar-nav .sidebar-nav-title { overflow: hidden; text-overflow: ellipsis; }
.sidebar-nav-collapsible-header { width: 100%; border: 0; font-family: inherit; text-align: left; }
.sidebar-nav .sidebar-nav-collapsible { margin-top: 4px; padding-top: 4px; }
.sidebar-nav .sidebar-nav-collapsible-content { display: none; }
.sidebar-nav.is-expanded .sidebar-nav-collapsible.expanded .sidebar-nav-collapsible-content { display: block; max-height: none; }
.sidebar-nav-link.is-current { background: color-mix(in srgb, var(--primary-color) 20%, transparent); color: var(--text-light, #fff); }
.sidebar-nav-link.is-current::before { transform: scaleY(1); }
.sidebar-menu-toggle:focus-visible,
.sidebar-nav-link:focus-visible,
.sidebar-nav-collapsible-header:focus-visible { outline: 2px solid #78c3bd; outline-offset: -3px; }
.sidebar-backdrop { display: none; }
body:has(.sidebar-nav.is-expanded) .sidebar-backdrop {
    display: block;
    position: fixed;
    inset: var(--navigation-top, 40px) 0 0;
    z-index: 9998;
    border: 0;
    background: rgb(0 0 0 / 20%);
    cursor: pointer;
}
@media (prefers-reduced-motion: reduce) {
    .sidebar-nav, .sidebar-nav * { transition: none !important; }
}

.sidebar-nav-header {
    padding: 16px 12px;
    border-bottom: 1px solid rgba(168, 85, 247, 0.2);
    white-space: nowrap;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.user-info {
    padding: 8px 12px;
    background: color-mix(in srgb, var(--primary-color) 15%, transparent);
    border-radius: 6px;
    border: 1px solid color-mix(in srgb, var(--primary-color) 30%, transparent);
    margin-bottom: 8px;
}

.username-display {
    color: var(--primary-color);
    font-weight: 600;
    font-size: 0.9em;
}

.theme-selector {
    display: flex;
    flex-direction: column;
    gap: 6px;
    opacity: 0;
    height: 0;
    overflow: hidden;
    transition: opacity 0.2s ease, height 0.2s ease;
}

.sidebar-nav.is-expanded .theme-selector {
    opacity: 1;
    height: auto;
}

.logout-btn, .login-link {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 10px 16px;
    margin-top: 12px;
    background: color-mix(in srgb, var(--danger-color, #EC4899) 20%, transparent);
    border: 2px solid var(--danger-color, #EC4899);
    border-radius: 8px;
    color: var(--danger-color, #EC4899);
    font-size: 0.9em;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.3s ease;
    text-decoration: none;
    width: 100%;
    justify-content: center;
}

.logout-btn:hover {
    background: color-mix(in srgb, var(--danger-color, #EC4899) 35%, transparent);
    transform: translateY(-2px);
    box-shadow: 0 4px 12px color-mix(in srgb, var(--danger-color, #EC4899) 30%, transparent);
}

.login-link {
    background: color-mix(in srgb, var(--primary-color) 20%, transparent);
    border-color: var(--primary-color);
    color: var(--primary-color);
}

.login-link:hover {
    background: color-mix(in srgb, var(--primary-color) 35%, transparent);
    transform: translateY(-2px);
    box-shadow: 0 4px 12px color-mix(in srgb, var(--primary-color) 30%, transparent);
}

.logout-btn .rune-icon, .login-link .rune-icon {
    width: 16px;
    height: 16px;
}

.theme-selector label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--secondary-color, #14B8A6);
}

.theme-selector select {
    background: color-mix(in srgb, var(--surface-panel) 85%, transparent 15%);
    border: 1px solid color-mix(in srgb, var(--primary-color) 40%, transparent);
    border-radius: 6px;
    color: var(--text-light, #E0E7FF);
    padding: 6px 8px;
    font-size: 13px;
    appearance: none;
    outline: none;
    cursor: pointer;
    transition: border-color 0.2s ease, box-shadow 0.2s ease;
}

.theme-selector select:hover,
.theme-selector select:focus {
    border-color: color-mix(in srgb, var(--primary-color) 60%, transparent);
    box-shadow: 0 0 12px color-mix(in srgb, var(--primary-color) 30%, transparent);
}

.sidebar-logo {
    max-width: 120px;
    width: auto;
    height: auto;
    max-height: 80px;
    margin: 0 auto 15px;
    display: block;
    filter: drop-shadow(0 0 8px rgba(168, 85, 247, 0.6));
    transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

/* Scale down logo when sidebar is collapsed */
.sidebar-nav:not(.is-expanded) .sidebar-logo {
    max-width: 40px;
    max-height: 40px;
    opacity: 0.8;
}

/* Full size when expanded */
.sidebar-nav.is-expanded .sidebar-logo {
    max-width: 120px;
    max-height: 80px;
    opacity: 1;
}

.sidebar-nav-title {
    color: var(--primary-color);
    font-size: 18px;
    font-weight: 600;
    margin: 0;
    opacity: 0;
    transition: opacity 0.2s;
}

.sidebar-nav.is-expanded .sidebar-nav-title {
    opacity: 1;
    transition-delay: 0.1s;
}

.sidebar-nav-links {
    padding: 12px 0;
}

.sidebar-nav-link {
    display: flex;
    align-items: center;
    padding: 12px 16px;
    color: rgba(255, 255, 255, 0.75);
    text-decoration: none;
    transition: all 0.2s;
    cursor: pointer;
    white-space: nowrap;
    position: relative;
    background: color-mix(in srgb, transparent 85%, var(--surface-panel) 15%);
    font-size: 0.9em;
}

.sidebar-nav-link:hover {
    background: color-mix(in srgb, var(--primary-color) 20%, transparent 80%);
    color: var(--primary-color);
}

.sidebar-nav-link::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 3px;
    background: var(--primary-color);
    transform: scaleY(0);
    transition: transform 0.2s;
}

.sidebar-nav-link:hover::before {
    transform: scaleY(1);
}

.sidebar-nav-icon {
    width: 22px;
    height: 22px;
    min-width: 22px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 18px;
    margin-right: 12px;
}

.sidebar-nav-icon > *:not(svg) {
    filter: grayscale(100%) brightness(2) opacity(0.8);
}

.sidebar-nav-text {
    opacity: 0;
    transition: opacity 0.2s;
}

.sidebar-nav.is-expanded .sidebar-nav-text {
    opacity: 1;
    transition-delay: 0.1s;
}

.sidebar-nav-collapsible {
    border-top: 1px solid rgba(168, 85, 247, 0.2);
    margin-top: 10px;
    padding-top: 10px;
}

.sidebar-nav-collapsible-header {
    display: flex;
    align-items: center;
    padding: 12px 16px;
    color: rgba(255, 255, 255, 0.75);
    cursor: pointer;
    transition: all 0.2s;
    white-space: nowrap;
    position: relative;
    background: color-mix(in srgb, transparent 85%, var(--surface-panel) 15%);
    user-select: none;
    font-size: 0.9em;
    font-weight: 500;
}

.sidebar-nav-collapsible-header:hover {
    background: color-mix(in srgb, var(--primary-color) 20%, transparent 80%);
    color: var(--primary-color);
}

.sidebar-nav-collapsible-toggle {
    margin-left: auto;
    font-size: 12px;
    transition: transform 0.2s;
    opacity: 0;
}

.sidebar-nav.is-expanded .sidebar-nav-collapsible-toggle {
    opacity: 1;
}

.sidebar-nav-collapsible.expanded .sidebar-nav-collapsible-toggle {
    transform: rotate(0deg);
}

.sidebar-nav-collapsible-content {
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.3s ease-out;
}

.sidebar-nav-collapsible.expanded .sidebar-nav-collapsible-content {
    max-height: 500px;
    transition: max-height 0.3s ease-in;
}

.sidebar-nav-sub-link {
    padding-left: 36px !important;
    font-size: 0.85em;
    opacity: 0.85;
    padding-top: 10px !important;
    padding-bottom: 10px !important;
}

.sidebar-nav-sub-link:hover {
    opacity: 1;
}

.page-header {
    margin-bottom: 48px;
    padding: 24px 0;
    border-bottom: 1px solid color-mix(in srgb, var(--border-color) 30%, transparent 70%);
}

.page-header h1 {
    font-size: 2.75em;
    color: var(--primary-color);
    margin: 0 0 12px 0;
    font-weight: 700;
    letter-spacing: -0.03em;
    text-shadow: 0 0 12px color-mix(in srgb, var(--primary-color) 35%, transparent);
    line-height: 1.2;
}

.page-header p {
    font-size: 1.15em;
    color: var(--text-dim);
    margin: 0;
    opacity: 0.9;
    font-weight: 400;
}


/* layout/_grid.css */
/**
 * Grid and Layout Components
 * Shared grid layouts and content wrappers
 */

/* Shared Content Wrapper */
.content-wrapper {
    padding: 20px 40px; /* Horizontal padding for readability - IDE style */
    margin: 0 auto; /* Center content */
    margin-top: 0; /* No top margin - page padding handles banner spacing - IDE style */
    max-width: 1600px; /* Max width for readability - IDE style */
    width: 100%;
    box-sizing: border-box;
}

/* Shared Item Grid - Full width cards with readable max-width */
.item-grid {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin: 12px auto 0; /* Center with top margin */
    width: 100%;
    max-width: 1600px; /* Max width for readability - IDE style */
    box-sizing: border-box;
}

/* Shared Controls */
.controls {
    margin: 20px 0;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 15px;
    flex-wrap: wrap;
}

.controls .button-group {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
    margin-left: auto;
}

/* Field Layouts */
.field-group {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.field-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 16px;
    align-items: start;
}

/* Campaigns Grid (Home Page)
   A shelf. Campaigns are browsed the way books are — a wall of covers you scan
   by shape and colour — so a column is the width of a cover, not the width of
   a paragraph. It used to be 380–420px of mostly text, which fitted two per row
   on a wide screen and read as a list pretending to be cards. */
.campaigns-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
    gap: 28px 24px;
    margin: 40px auto 0;
    width: 100%;
    max-width: 1600px;
    box-sizing: border-box;
}

@media (max-width: 560px) {
    .campaigns-grid {
        grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
        gap: 20px 16px;
    }
}

/* Actions Container */
.actions {
    display: flex;
    gap: 15px;
    justify-content: flex-end;
    margin-top: 20px;
}


/* components/_buttons.css */
/**
 * Button Components
 * Consolidated button styles - removes duplicates and standardizes patterns
 */

/* Base Button */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 4px 8px;
    border: 1px solid color-mix(in srgb, var(--border-color) 80%, transparent);
    background: color-mix(in srgb, var(--surface-panel) 85%, transparent 15%);
    color: var(--text-light);
    font-size: 0.7em;
    font-weight: 600;
    border-radius: 4px;
    cursor: pointer;
    transition: transform 0.2s ease, box-shadow 0.25s ease, background 0.2s ease, border-color 0.2s ease, color 0.2s ease;
    text-decoration: none;
    backdrop-filter: blur(10px);
}

.btn svg,
.btn .rune-icon {
    width: 14px;
    height: 14px;
}

.btn:hover {
    transform: translateY(-2px);
    box-shadow: 0 12px 25px color-mix(in srgb, var(--shadow-color) 30%, transparent);
    border-color: var(--primary-color);
}

/* Button Variants - Consolidated */
.btn-primary,
.btn-secondary,
.btn-accent,
.btn-danger {
    background: color-mix(in srgb, var(--surface-panel) 85%, transparent 15%);
    border-color: color-mix(in srgb, var(--border-color) 80%, transparent);
    color: var(--text-light);
}

.btn-primary:hover,
.btn-secondary:hover,
.btn-accent:hover,
.btn-danger:hover {
    background: color-mix(in srgb, var(--surface-panel) 95%, transparent 5%);
    box-shadow: 0 10px 20px color-mix(in srgb, var(--shadow-color) 30%, transparent);
    color: var(--text-light);
    border-color: var(--primary-color);
}

/* Button Sizes */
.btn-small {
    padding: 3px 6px;
    min-width: 24px;
    font-size: 0.65em;
    border-width: 1px;
    gap: 4px;
}

.btn-small svg,
.btn-small .rune-icon {
    width: 12px;
    height: 12px;
}

.btn-block {
    display: block;
    width: 100%;
}

/* Specialized Buttons - Consolidated from .btn-rune, .btn-edit */
.btn-rune,
.btn-edit {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 6px 12px;
    background: color-mix(in srgb, var(--primary-color) 20%, transparent);
    border: 1px solid var(--abyssal-glow);
    border-radius: 4px;
    color: var(--abyssal-glow);
    font-size: 0.85em;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.2s ease;
}

.btn-rune {
    padding: 10px 20px;
    border-radius: 6px;
    border-width: 2px;
    transition: all 0.3s ease;
}

.btn-rune:hover,
.btn-edit:hover {
    background: color-mix(in srgb, var(--primary-color) 40%, transparent);
    transform: translateY(-2px);
    box-shadow: 0 0 15px color-mix(in srgb, var(--primary-color) 40%, transparent);
}

.btn-rune .rune-icon {
    transition: all 0.3s ease;
}

.btn-rune:hover .rune-icon {
    filter: drop-shadow(0 0 4px currentColor);
}

/* Remove Buttons - Consolidated from .btn-remove and .btn-remove-user */
.btn-remove,
.btn-remove-user {
    padding: 6px 12px;
    background: color-mix(in srgb, var(--danger-color) 20%, transparent);
    border: 1px solid var(--abyssal-accent);
    border-radius: 4px;
    color: var(--abyssal-accent);
    cursor: pointer;
    font-size: 0.85em;
    font-weight: 600;
    transition: all 0.2s ease;
}

.btn-remove-user {
    width: 22px;
    height: 22px;
    min-width: 22px;
    min-height: 22px;
    padding: 0;
    display: inline-flex !important;
    font-size: 16px;
    border-color: color-mix(in srgb, var(--danger-color) 50%, transparent);
    color: rgba(255, 255, 255, 0.9);
}

.btn-remove:hover,
.btn-remove-user:hover {
    background: color-mix(in srgb, var(--danger-color) 40%, transparent);
}

.btn-remove-user:hover {
    border-color: color-mix(in srgb, var(--danger-color) 70%, transparent);
    color: rgba(255, 255, 255, 1);
}

.btn-remove-user:active {
    background: color-mix(in srgb, var(--danger-color) 60%, transparent);
    transform: scale(0.95);
}

/* Icon Images in Buttons */
.btn .icon-img {
    width: 22px;
    height: 22px;
}

.btn-small .icon-img {
    width: 18px;
    height: 18px;
}


/* components/_modals.css */
/**
 * Modal Components
 * Consolidated modal styles
 * 
 * Used by:
 * - All form-list pages (factions, shops, classes, races, features, backgrounds, geography)
 * - Story page
 * - Character/NPC detail pages
 * - All modal dialogs across the application
 * 
 * All modals should use these shared styles for consistency.
 */

.modal {
    display: none;
    position: fixed;
    z-index: 1000;
    left: 0 !important; /* Full screen, ignore page padding */
    top: 0 !important; /* Full screen, ignore page padding */
    width: 100vw !important; /* Full viewport width */
    height: 100vh !important; /* Full viewport height */
    background-color: rgba(0, 0, 0, 0.8);
    backdrop-filter: blur(5px);
    /* Modals are full-screen overlays, not affected by page padding or sidebar */
    padding: 0 !important;
    margin: 0 !important;
    box-sizing: border-box;
}

/* Ensure modal content doesn't inherit any padding from parent pages */
.modal * {
    box-sizing: border-box;
}

.modal.show {
    display: flex;
    align-items: center;
    justify-content: center;
}

.modal-content {
    background: color-mix(in srgb, var(--surface-base, var(--theme-color-2, #2d2d3a)) 95%, transparent);
    border: 2px solid var(--border-color);
    border-radius: 16px;
    padding: 40px;
    max-width: 600px;
    width: 90%;
    max-height: 80vh;
    overflow-y: auto;
    position: relative;
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
    backdrop-filter: blur(10px);
}

.modal-content.modal-large {
    max-width: 900px;
    width: 95%;
}

.modal-content h2 {
    color: var(--primary-color);
    margin-bottom: 20px;
}

.modal-content h3 {
    color: var(--secondary-color);
    margin-top: 25px;
    margin-bottom: 10px;
}

.modal-content p,
.modal-content li {
    line-height: 1.8;
    margin-bottom: 15px;
}

.modal-content code {
    background: rgba(0, 0, 0, 0.3);
    padding: 2px 6px;
    border-radius: 4px;
    color: var(--primary-color);
    font-family: 'Courier New', monospace;
}

.modal-content ul,
.modal-content ol {
    margin-left: 25px;
}

/* Modal Headers */
.modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;
}

.modal-header h2 {
    margin: 0;
    color: var(--primary-color);
}

.modal-header-close {
    padding: 8px 16px;
}

.modal-title-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 12px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--panel-60);
}

.modal-title-header h2 {
    margin: 0;
    font-size: 1.3em;
}

.modal-title-close {
    padding: 4px 12px;
}

.close,
.close-new {
    position: absolute;
    right: 20px;
    top: 20px;
    font-size: 28px;
    font-weight: bold;
    color: var(--text-dim);
    cursor: pointer;
    transition: color 0.3s ease;
}

.close:hover,
.close-new:hover {
    color: var(--accent-color);
}

.modal-actions {
    display: flex;
    gap: 15px;
    justify-content: flex-end;
    margin-top: 20px;
}

.modal-actions .btn {
    padding: 12px 30px;
}

.detail-content {
    max-height: 80vh;
    overflow-y: auto;
}

/* Database Modal Search Controls */
.modal-content input[type="text"],
.modal-content select {
    padding: 12px;
    background: color-mix(in srgb, var(--panel-60, var(--theme-color-2)) 100%, transparent);
    border: 2px solid var(--primary-color, var(--abyssal-glow));
    border-radius: 6px;
    color: var(--text-light, var(--abyssal-light));
    font-size: 14px;
}

.modal-content input[type="text"]:focus,
.modal-content select:focus {
    outline: none;
    border-color: var(--accent-color, var(--abyssal-accent));
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-color, var(--abyssal-accent)) 20%, transparent);
}

/* Database Modal Grid Containers */
.modal-content [id$="-db-grid"] {
    display: flex;
    flex-direction: column;
    gap: 12px;
    max-height: 60vh;
    overflow-y: auto;
}

.modal-content #feature-db-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: 15px;
    max-height: 60vh;
    overflow-y: auto;
}

/* Database Modal Footer Note */
.modal-content > div:last-child:not(.modal-header):not([id$="-db-grid"]) {
    margin-top: 20px;
    text-align: center;
    color: var(--text-light, var(--abyssal-light));
    opacity: 0.6;
    font-size: 0.9em;
}

/* Ensure edit form fields are only visible inside the modal */
#character-detail-container #spell-slots-mode,
#character-detail-container #mp-system-mode,
#character-detail-container #item-parent,
#character-detail-container .form-group:has(#item-parent) {
    display: none !important;
}

/* Only show these fields when inside the modal */
.modal #spell-slots-mode,
.modal #mp-system-mode,
.modal #item-parent {
    display: block;
}


/* components/_trading-card-modal.css */
/**
 * Trading Card Modal Styles
 * Apply to any edit modal by adding class "trading-card-modal" to the modal element
 * 
 * Usage: <div id="modal" class="modal trading-card-modal">
 * 
 * All colors use theme variables - no hardcoded colors
 */

/* Trading Card Style Modal - General */
.modal.trading-card-modal .modal-content {
    max-width: 1000px;
    width: 90%;
    max-height: 85vh;
    background: linear-gradient(135deg, 
        var(--surface-panel) 0%, 
        var(--surface-base) 50%,
        var(--surface-panel) 100%);
    border: 3px solid var(--accent-color);
    border-radius: 20px;
    padding: 0;
    box-shadow: 
        0 0 30px var(--shadow-primary-35),
        0 20px 60px var(--shadow-ambient-55),
        inset 0 0 20px var(--accent-primary-20);
    position: relative;
    overflow-y: auto !important;
    overflow-x: hidden !important;
    transform-style: preserve-3d;
}

/* Card-like header section */
.modal.trading-card-modal .modal-content::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 120px;
    background: linear-gradient(180deg, 
        var(--accent-primary-35) 0%,
        var(--accent-primary-20) 50%,
        transparent 100%);
    pointer-events: none;
    z-index: 0;
}

/* Card title area - works with various title IDs */
.modal.trading-card-modal #modal-title,
.modal.trading-card-modal #detail-title,
.modal.trading-card-modal .modal-content h2:first-child {
    position: relative;
    z-index: 1;
    padding: 20px 25px 15px;
    margin: 0;
    font-size: 1.5em;
    font-weight: 700;
    text-align: center;
    color: var(--abyssal-glow);
    text-shadow: 
        0 0 10px var(--shadow-primary-50),
        0 2px 4px var(--shadow-ambient-55);
    border-bottom: 2px solid var(--accent-primary-35);
    background: linear-gradient(180deg, 
        var(--accent-primary-20) 0%,
        transparent 100%);
}

/* Form container with card-like styling */
.modal.trading-card-modal #item-form,
.modal.trading-card-modal form {
    padding: 25px;
    position: relative;
    z-index: 1;
    background: transparent;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

/* Form groups with card section styling - ALL ROUNDED AND SAME COLOR */
.modal.trading-card-modal .form-group {
    margin: 0;
    padding: 12px;
    background: var(--panel-60) !important;
    border: 1px solid var(--outline-soft) !important;
    border-radius: 8px !important;
    transition: all 0.3s ease;
}

.modal.trading-card-modal .form-group:hover {
    background: var(--panel-75) !important;
    border-color: var(--outline-strong) !important;
    box-shadow: 0 0 10px var(--shadow-primary-25);
}

/* Ensure all grid containers and their children are rounded */
.modal.trading-card-modal [style*="grid-template-columns"] {
    gap: 12px !important;
}

.modal.trading-card-modal [style*="grid-template-columns"] > * {
    border-radius: 8px !important;
    background: var(--panel-60) !important;
    border: 1px solid var(--outline-soft) !important;
    padding: 12px !important;
    transition: all 0.3s ease !important;
}

.modal.trading-card-modal [style*="grid-template-columns"] > *:hover {
    background: var(--panel-75) !important;
    border-color: var(--outline-strong) !important;
    box-shadow: 0 0 10px var(--shadow-primary-25) !important;
}

/* Labels with card-style typography */
.modal.trading-card-modal .form-group label {
    display: block;
    font-size: 0.8em;
    font-weight: 600;
    margin-bottom: 6px;
    color: var(--abyssal-glow);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    text-shadow: 0 1px 2px var(--shadow-ambient-40);
}

/* Input fields with card-style appearance - ALL ROUNDED */
.modal.trading-card-modal input[type="text"],
.modal.trading-card-modal input[type="number"],
.modal.trading-card-modal input[type="email"],
.modal.trading-card-modal input[type="url"],
.modal.trading-card-modal select,
.modal.trading-card-modal textarea {
    width: 100%;
    padding: 8px 12px;
    font-size: 0.9em;
    background: var(--panel-40) !important;
    border: 1px solid var(--accent-primary-35) !important;
    border-radius: 8px !important;
    color: var(--text-light);
    transition: all 0.3s ease;
    font-family: inherit;
}

/* Spell slot number inputs need extra right padding for spinner arrows */
.modal.trading-card-modal input[type="number"][id^="spell-slots-"] {
    padding-right: 24px !important;
}

.modal.trading-card-modal input[type="text"]:focus,
.modal.trading-card-modal input[type="number"]:focus,
.modal.trading-card-modal input[type="email"]:focus,
.modal.trading-card-modal input[type="url"]:focus,
.modal.trading-card-modal select:focus,
.modal.trading-card-modal textarea:focus {
    outline: none;
    border-color: var(--abyssal-glow) !important;
    background: var(--panel-60) !important;
    box-shadow: 
        0 0 10px var(--shadow-primary-35),
        inset 0 0 10px var(--accent-primary-20);
}

/* Select dropdowns */
.modal.trading-card-modal select {
    cursor: pointer;
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23a855f7' d='M6 9L1 4h10z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 10px center;
    padding-right: 30px;
}

/* Textarea */
.modal.trading-card-modal textarea {
    resize: vertical;
    min-height: 80px;
    font-family: inherit;
}

/* Image preview with card frame - ROUNDED */
.modal.trading-card-modal #image-preview,
.modal.trading-card-modal .image-preview {
    margin-top: 8px;
    padding: 12px;
    background: var(--panel-60) !important;
    border: 1px solid var(--outline-soft) !important;
    border-radius: 8px !important;
    min-height: 120px;
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative;
    overflow: hidden;
}

.modal.trading-card-modal #image-preview img,
.modal.trading-card-modal .image-preview img {
    max-width: 100%;
    max-height: 200px;
    border-radius: 6px;
    box-shadow: 0 4px 12px var(--shadow-ambient-40);
}

/* Checkbox labels (skill proficiencies, etc.) - ROUNDED AND SAME COLOR */
.modal.trading-card-modal .checkbox-label {
    padding: 6px 10px;
    background: var(--panel-60) !important;
    border: 1px solid var(--outline-soft) !important;
    border-radius: 8px !important;
    transition: all 0.2s ease;
    font-size: 0.85em;
}

.modal.trading-card-modal .checkbox-label:hover {
    background: var(--panel-75) !important;
    border-color: var(--outline-strong) !important;
}

.modal.trading-card-modal .checkbox-label input[type="checkbox"] {
    margin-right: 6px;
    accent-color: var(--abyssal-glow);
}

/* Card-style button section at bottom */
.modal.trading-card-modal .form-group:last-of-type,
.modal.trading-card-modal [style*="justify-content: flex-end"] {
    margin-top: 20px;
    padding: 20px 0 0;
    border-top: 2px solid var(--accent-primary-35);
    background: transparent !important;
    border-radius: 0 !important;
}

/* Buttons with card-style appearance */
.modal.trading-card-modal .btn {
    padding: 12px 24px;
    font-size: 0.95em;
    font-weight: 600;
    border-radius: 8px !important;
    transition: all 0.3s ease;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    box-shadow: 0 4px 12px var(--shadow-ambient-40);
}

.modal.trading-card-modal .btn-primary {
    background: linear-gradient(135deg, var(--abyssal-glow) 0%, var(--accent-primary-35) 100%);
    border: 2px solid var(--abyssal-glow);
    color: var(--text-dark);
    text-shadow: 0 1px 2px var(--shadow-ambient-30);
}

.modal.trading-card-modal .btn-primary:hover {
    background: linear-gradient(135deg, var(--accent-primary-35) 0%, var(--abyssal-glow) 100%);
    box-shadow: 
        0 0 20px var(--shadow-primary-50),
        0 6px 16px var(--shadow-ambient-55);
    transform: translateY(-2px);
}

.modal.trading-card-modal .btn-secondary {
    background: var(--accent-primary-20);
    border: 2px solid var(--abyssal-glow);
    color: var(--abyssal-glow);
}

.modal.trading-card-modal .btn-secondary:hover {
    background: var(--accent-primary-35);
    box-shadow: 0 0 15px var(--shadow-primary-35);
}

/* Scrollbar styling for card aesthetic - ALWAYS VISIBLE */
.modal.trading-card-modal .modal-content {
    scrollbar-width: thin;
    scrollbar-color: var(--accent-primary-35) var(--panel-40);
}

.modal.trading-card-modal .modal-content::-webkit-scrollbar {
    width: 12px;
}

.modal.trading-card-modal .modal-content::-webkit-scrollbar-track {
    background: var(--panel-40);
    border-radius: 6px;
    margin: 5px;
}

.modal.trading-card-modal .modal-content::-webkit-scrollbar-thumb {
    background: var(--accent-primary-35);
    border-radius: 6px;
    border: 2px solid var(--panel-40);
    min-height: 40px;
}

.modal.trading-card-modal .modal-content::-webkit-scrollbar-thumb:hover {
    background: var(--accent-primary-50);
}

/* Spell slots section with card-style grid - ROUNDED AND SAME COLOR */
.modal.trading-card-modal #spell-slot-inputs,
.modal.trading-card-modal [id*="spell-slot"] {
    background: var(--panel-60) !important;
    padding: 12px;
    border-radius: 8px !important;
    border: 1px solid var(--outline-soft);
}

/* Skill proficiencies grid - ROUNDED AND SAME COLOR */
.modal.trading-card-modal [style*="grid-template-columns: repeat(auto-fit"] {
    background: var(--panel-60) !important;
    padding: 12px;
    border-radius: 8px !important;
    border: 1px solid var(--outline-soft);
}

/* Custom input fields (race, class, background) */
.modal.trading-card-modal input[id*="-custom"] {
    margin-top: 8px;
    border-style: dashed;
    border-color: var(--accent-primary-35);
}

/* File input styling - ROUNDED */
.modal.trading-card-modal input[type="file"] {
    padding: 8px;
    background: var(--panel-40) !important;
    border: 1px dashed var(--accent-primary-35) !important;
    border-radius: 8px !important;
    color: var(--text-light);
    cursor: pointer;
    transition: all 0.3s ease;
}

.modal.trading-card-modal input[type="file"]:hover {
    border-color: var(--accent-primary-50) !important;
    background: var(--panel-60) !important;
}

/* Required field indicator */
.modal.trading-card-modal input[required] {
    border-left: 3px solid var(--abyssal-glow);
}

/* Special styling for ability scores section (card stats) */
.modal.trading-card-modal [style*="grid-template-columns: repeat(6"] {
    gap: 8px !important;
}

.modal.trading-card-modal [style*="grid-template-columns: repeat(6"] .form-group {
    text-align: center;
    padding: 10px 8px;
}

.modal.trading-card-modal [style*="grid-template-columns: repeat(6"] .form-group label {
    font-size: 0.7em;
    margin-bottom: 4px;
}

.modal.trading-card-modal [style*="grid-template-columns: repeat(6"] input {
    text-align: center;
    font-weight: 600;
    font-size: 1em;
}

/* Detail modal header styling */
.modal.trading-card-modal .modal-title-header {
    position: relative;
    z-index: 1;
    padding: 20px 25px 15px;
    margin: 0 0 0 0;
    border-bottom: 2px solid var(--accent-primary-35);
    background: linear-gradient(180deg, 
        var(--accent-primary-20) 0%,
        transparent 100%);
}

.modal.trading-card-modal .modal-title-header h2 {
    color: var(--abyssal-glow);
    text-shadow: 
        0 0 10px var(--shadow-primary-50),
        0 2px 4px var(--shadow-ambient-55);
}

/* Responsive adjustments */
@media (max-width: 768px) {
    .modal.trading-card-modal .modal-content {
        width: 95%;
        max-height: 90vh;
        padding: 0;
    }
    
    .modal.trading-card-modal #item-form,
    .modal.trading-card-modal form {
        padding: 20px 15px;
    }
    
    .modal.trading-card-modal #modal-title,
    .modal.trading-card-modal #detail-title,
    .modal.trading-card-modal .modal-content h2:first-child {
        font-size: 1.3em;
        padding: 15px 20px 12px;
    }
}


/* components/_edit-modal-forms.css */
/**
 * Edit Modal Form Styles
 * Shared styles for character and NPC edit modals
 * All inline styles extracted from character-detail.html and npc-detail.html
 */

/* Modal Content */
.modal.trading-card-modal .modal-content {
    max-width: 700px;
    max-height: 90vh;
    overflow-y: auto;
    padding: 15px;
}

/* Modal Title */
.modal.trading-card-modal #modal-title {
    margin: 0 0 12px 0;
    font-size: 1.3em;
}

/* Form Container */
.modal.trading-card-modal #item-form {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

/* Form Groups */
.modal.trading-card-modal #item-form .form-group {
    margin: 0;
}

/* Grid Layouts - First row (Name, Type, Level) */
/* :not(.form-group) matters: on the character sheet the first child is a bare
   wrapper holding three fields, but on every other edit modal it IS the Name
   form-group. Without the guard this grid put that single label and input in
   separate columns, which is why Name looked like a different form. */
.modal.trading-card-modal #item-form > div:first-of-type:not(.form-group) {
    display: grid;
    grid-template-columns: 2fr 1fr 1fr;
    gap: 4px;
}

/* Grid: Race, Class, Faction */
.modal.trading-card-modal #item-form > div:has(#item-race),
.modal.trading-card-modal #item-form > div:has(#item-class):not(.form-group) {
    display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    gap: 4px;
}

/* Grid: Background, Languages */
.modal.trading-card-modal #item-form > div:has(#item-background):not(.form-group),
.modal.trading-card-modal #item-form > div:has(#item-languages):not(.form-group) {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 4px;
}

/* Grid: Spellcasting, Image */
.modal.trading-card-modal #item-form > div:has(#item-spellcasting-ability) {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 6px;
}

/* Grid: Currency (Gold, Silver, Copper) */
.modal.trading-card-modal #item-form > div:has(#item-currency-gold) {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 6px;
}

/* Grid: Hit Dice */
.modal.trading-card-modal #item-form > div:has(#item-hit-dice-type) {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 6px;
}

/* Labels - Standard form group labels */
.modal.trading-card-modal #item-form .form-group > label:first-child {
    font-size: 0.75em;
    margin-bottom: 2px;
}

/* Labels - Larger labels (0.85em) */
.modal.trading-card-modal #item-form .form-group > label[for="item-description"],
.modal.trading-card-modal #item-form .form-group > label[for="item-parent"],
.modal.trading-card-modal #item-form .form-group > label:contains("Stats"),
.modal.trading-card-modal #item-form .form-group > label:contains("Skills"),
.modal.trading-card-modal #item-form .form-group > label:contains("Spell Slots") {
    font-size: 0.85em;
    margin-bottom: 4px;
}

.modal.trading-card-modal #item-form .form-group > label:contains("Stats"),
.modal.trading-card-modal #item-form .form-group > label:contains("Spell Slots") {
    margin-bottom: 6px;
}

/* Labels - Currency and Hit Dice (teal) */
.modal.trading-card-modal #item-form .form-group > label[for^="item-currency-"],
.modal.trading-card-modal #item-form .form-group > label[for="item-hit-dice-type"],
.modal.trading-card-modal #item-form .form-group > label[for="item-max-hit-dice"],
.modal.trading-card-modal #item-form .form-group > label[for="item-current-hit-dice"] {
    font-size: 0.85em;
    margin-bottom: 4px;
    color: var(--abyssal-teal);
}

/* Labels - Stats grid (teal, smaller) */
.modal.trading-card-modal #item-form .form-group > div > label {
    font-size: 0.75em;
    color: var(--abyssal-teal);
    display: block;
    margin-bottom: 2px;
}

/* Labels - Spell slots (smallest, teal) */
.modal.trading-card-modal #item-form .form-group > div:has(#spell-slots-cantrip) > div > label {
    font-size: 0.7em;
    color: var(--abyssal-teal);
    display: block;
    margin-bottom: 2px;
}

/* Inputs - Standard text/number */
.modal.trading-card-modal #item-form input[type="text"]:not([id*="-custom"]):not(#item-speed),
.modal.trading-card-modal #item-form input[type="number"]:not([id^="spell-slots-"]):not([id^="item-str"]):not([id^="item-dex"]):not([id^="item-con"]):not([id^="item-int"]):not([id^="item-wis"]):not([id^="item-cha"]):not([id^="item-base-ac"]):not([id^="item-current-ac"]):not([id^="item-max-hp"]):not([id^="item-current-hp"]):not([id^="item-temp-hp"]) {
    padding: 4px;
    font-size: 0.85em;
}

/* Inputs - Currency, Hit Dice, Parent */
.modal.trading-card-modal #item-form input[id^="item-currency-"],
.modal.trading-card-modal #item-form input[id^="item-max-hit-dice"],
.modal.trading-card-modal #item-form input[id^="item-current-hit-dice"],
.modal.trading-card-modal #item-form input[id="item-parent"] {
    padding: 6px;
    font-size: 0.9em;
}

/* Inputs - Stats (centered) */
.modal.trading-card-modal #item-form input[id^="item-str"],
.modal.trading-card-modal #item-form input[id^="item-dex"],
.modal.trading-card-modal #item-form input[id^="item-con"],
.modal.trading-card-modal #item-form input[id^="item-int"],
.modal.trading-card-modal #item-form input[id^="item-wis"],
.modal.trading-card-modal #item-form input[id^="item-cha"],
.modal.trading-card-modal #item-form input[id^="item-base-ac"],
.modal.trading-card-modal #item-form input[id^="item-current-ac"],
.modal.trading-card-modal #item-form input[id^="item-max-hp"],
.modal.trading-card-modal #item-form input[id^="item-current-hp"],
.modal.trading-card-modal #item-form input[id^="item-temp-hp"],
.modal.trading-card-modal #item-form input[id="item-speed"] {
    padding: 4px;
    font-size: 0.85em;
    text-align: center;
}

/* Spell Slot Inputs - Extra right padding for spinner arrows */
.modal.trading-card-modal #item-form input[type="number"][id^="spell-slots-"] {
    width: 100%;
    padding: 4px 24px 4px 4px !important;
    font-size: 0.85em;
    text-align: center;
}

/* Selects - Standard */
.modal.trading-card-modal #item-form select:not([id="item-token-size"]):not([id="item-hit-dice-type"]) {
    padding: 4px;
    font-size: 0.85em;
}

/* Selects - Spellcasting, Currency, Hit Dice, Parent */
.modal.trading-card-modal #item-form select[id="item-spellcasting-ability"],
.modal.trading-card-modal #item-form select[id^="item-currency-"],
.modal.trading-card-modal #item-form select[id="item-hit-dice-type"],
.modal.trading-card-modal #item-form select[id="item-parent"] {
    padding: 6px;
    font-size: 0.9em;
}

/* Selects - Token Size (special styling) */
.modal.trading-card-modal #item-form select[id="item-token-size"] {
    width: 100%;
    padding: 4px;
    font-size: 0.85em;
    text-align: center;
    background: rgba(27, 42, 106, 0.5);
    border: 1px solid var(--abyssal-glow);
    border-radius: 4px;
    color: var(--abyssal-light);
}

/* Selects - Hit Dice Type (special styling) */
.modal.trading-card-modal #item-form select[id="item-hit-dice-type"] {
    width: 100%;
    background: rgba(27, 42, 106, 0.5);
    border: 1px solid var(--abyssal-glow);
    border-radius: 4px;
    color: var(--abyssal-light);
}

/* File Input */
.modal.trading-card-modal #item-form input[type="file"] {
    padding: 4px;
    font-size: 0.85em;
}

/* Textarea */
.modal.trading-card-modal #item-form textarea {
    padding: 6px;
    font-size: 0.9em;
    min-height: 60px;
    resize: vertical;
}

/* Image Preview */
.modal.trading-card-modal #item-form #image-preview,
.modal.trading-card-modal #item-form .image-preview {
    margin-top: 4px;
}

/* Custom Input Fields */
.modal.trading-card-modal #item-form input[id*="-custom"] {
    padding: 4px;
    font-size: 0.85em;
    margin-top: 2px;
    display: none;
}

/* Stats Grid - First row (abilities) */
.modal.trading-card-modal #item-form .form-group > div:has(#item-str) {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 4px;
}

/* Stats Grid - Second row (AC, HP, etc) */
.modal.trading-card-modal #item-form .form-group > div:has(#item-base-ac) {
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 4px;
    margin-top: 6px;
}

/* Stats Grid - Token Size */
.modal.trading-card-modal #item-form .form-group > div:has(#item-token-size) {
    display: grid;
    grid-template-columns: 1fr;
    gap: 4px;
    margin-top: 6px;
}

/* Skills Container - Character (4 columns) */
.modal.trading-card-modal #item-form .form-group > div:has(#skill-acrobatics):not(:has(> div)) {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 2px;
    max-height: 120px;
    overflow-y: auto;
    padding: 4px;
    background: var(--panel-40);
    border-radius: 3px;
    font-size: 0.75em;
}

/* Skills Container - NPC (3 columns, wrapped) */
.modal.trading-card-modal #item-form .form-group > div:has(#skill-acrobatics):has(> div) {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 4px;
    max-height: 200px;
    overflow-y: auto;
    padding: 8px;
    background: var(--panel-40);
    border-radius: 4px;
}

/* Skill Labels - Character (direct label) */
.modal.trading-card-modal #item-form .form-group > div:has(#skill-acrobatics):not(:has(> div)) > label {
    display: flex;
    align-items: center;
    gap: 3px;
    margin: 0;
    cursor: pointer;
}

.modal.trading-card-modal #item-form .form-group > div:has(#skill-acrobatics):not(:has(> div)) > label input[type="checkbox"] {
    width: auto;
    margin: 0;
}

/* Skill Labels - NPC (wrapped in div) */
.modal.trading-card-modal #item-form .form-group > div:has(#skill-acrobatics):has(> div) > div {
    display: flex;
    align-items: center;
    gap: 4px;
}

.modal.trading-card-modal #item-form .form-group > div:has(#skill-acrobatics):has(> div) > div input[type="checkbox"] {
    width: auto;
    margin: 0;
}

.modal.trading-card-modal #item-form .form-group > div:has(#skill-acrobatics):has(> div) > div label {
    margin: 0;
    font-size: 0.8em;
    color: var(--abyssal-light);
    flex: 1;
}

/* Spell Slots Container */
.modal.trading-card-modal #item-form .form-group > div:has(#spell-slots-cantrip),
.modal.trading-card-modal #item-form #spell-slots-mode > div:has(#spell-slots-cantrip) {
    display: grid;
    grid-template-columns: repeat(10, 1fr);
    gap: 4px;
}

/* Spell Slots Header (MP System toggle) */
.modal.trading-card-modal #item-form .form-group > div:has(#use-mp-system) {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 6px;
}

.modal.trading-card-modal #item-form .form-group > div:has(#use-mp-system) > label {
    font-size: 0.85em;
}

.modal.trading-card-modal #item-form .form-group > div:has(#use-mp-system) > div {
    display: flex;
    align-items: center;
    gap: 8px;
}

.modal.trading-card-modal #item-form .form-group > div:has(#use-mp-system) > div label {
    font-size: 0.75em;
    color: var(--abyssal-light);
    opacity: 0.8;
}

.modal.trading-card-modal #item-form .form-group > div:has(#use-mp-system) > div input[type="checkbox"] {
    width: 18px;
    height: 18px;
    cursor: pointer;
}

/* MP System */
.modal.trading-card-modal #item-form #mp-system-mode {
    display: none;
}

.modal.trading-card-modal #item-form #mp-system-mode > div:has(#current-mp) {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px;
    background: rgba(27, 42, 106, 0.2);
    border-radius: 4px;
}

.modal.trading-card-modal #item-form #mp-system-mode > div:has(#current-mp) > div:first-child,
.modal.trading-card-modal #item-form #mp-system-mode > div:has(#current-mp) > div:last-child {
    flex: 1;
}

.modal.trading-card-modal #item-form #mp-system-mode > div:has(#current-mp) > div:first-child label,
.modal.trading-card-modal #item-form #mp-system-mode > div:has(#current-mp) > div:last-child label {
    font-size: 0.75em;
    color: var(--abyssal-light);
    opacity: 0.8;
    display: block;
    margin-bottom: 4px;
}

.modal.trading-card-modal #item-form #mp-system-mode > div:has(#current-mp) > div:first-child input,
.modal.trading-card-modal #item-form #mp-system-mode > div:has(#current-mp) > div:last-child div {
    width: 100%;
    padding: 6px;
    font-size: 0.9em;
    text-align: center;
    background: rgba(27, 42, 106, 0.4);
    border: 1px solid var(--abyssal-glow);
    border-radius: 3px;
    color: var(--abyssal-light);
}

.modal.trading-card-modal #item-form #mp-system-mode > div:has(#current-mp) > div:nth-child(2) {
    font-size: 1.2em;
    color: var(--abyssal-light);
    opacity: 0.6;
}

.modal.trading-card-modal #item-form #mp-system-mode > div:last-child {
    margin-top: 6px;
    font-size: 0.7em;
    color: var(--abyssal-light);
    opacity: 0.7;
    text-align: center;
}

.modal.trading-card-modal #item-form #mp-system-mode #max-mp-display {
    color: var(--abyssal-glow);
    font-weight: 600;
}

/* Visual Spell Slots */
.modal.trading-card-modal #item-form #visual-spell-slots {
    margin-top: 8px;
    padding: 8px;
    background: rgba(27, 42, 106, 0.2);
    border-radius: 4px;
    display: none;
}

.modal.trading-card-modal #item-form #visual-spell-slots > div {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
}

/* Modal Actions */
.modal.trading-card-modal #item-form .modal-actions {
    display: flex;
    gap: 8px;
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px solid rgba(168, 85, 247, 0.3);
}

.modal.trading-card-modal #item-form .modal-actions button {
    flex: 1;
    padding: 8px;
    font-size: 0.9em;
}

/* ============================================================================
   Everything above is character-sheet density.
   ----------------------------------------------------------------------------
   This file was written for the character and NPC edit modals, which fit forty
   fields in one dialog and need every pixel. But it is scoped to
   `.trading-card-modal #item-form`, and that is EVERY edit modal in the app —
   so classes, races, backgrounds, features, conditions, shops, factions, maps
   and tables, which have eight or ten fields and plenty of room, inherited a
   layout built for the opposite problem: 4px between groups, 0.75em labels 2px
   off their inputs, 4px input padding.

   The app's own form styling (css/components/_forms.css) is already the right
   shape — it is what login and account-settings use, and those read fine. So
   the fix is to stop the compression from reaching forms that never needed it,
   not to invent a third set of numbers.

   `:has(#item-str)` is the character sheet: it is the only form with ability
   scores. Everything that is not it gets the base form styling back.
   ========================================================================= */

.modal.trading-card-modal .modal-content:not(:has(#item-str)) {
    padding: 26px 28px;
}

.modal.trading-card-modal #modal-title:not(:has(~ #item-form #item-str)) {
    margin: 0 0 20px 0;
    font-size: 1.45em;
    padding-bottom: 14px;
    border-bottom: 1px solid var(--panel-60, rgba(255, 255, 255, 0.12));
}

.modal.trading-card-modal #item-form:not(:has(#item-str)) {
    gap: 0;                       /* the groups carry their own spacing again */
}

.modal.trading-card-modal #item-form:not(:has(#item-str)) .form-group {
    margin: 0 0 20px 0;
}

.modal.trading-card-modal #item-form:not(:has(#item-str)) .form-group:last-of-type {
    margin-bottom: 24px;
}

.modal.trading-card-modal #item-form:not(:has(#item-str)) .form-group > label:first-child {
    display: block;
    font-size: 0.95em;
    font-weight: 600;
    margin-bottom: 8px;
    color: var(--text-light);
}

/* The per-control rules above carry two ids each, so these have to as well to
   reach them — hence the second :not(), which is true of the same form. */
.modal.trading-card-modal #item-form:not(:has(#item-str)):not(:has(#item-base-ac)) input[type="text"],
.modal.trading-card-modal #item-form:not(:has(#item-str)):not(:has(#item-base-ac)) input[type="number"],
.modal.trading-card-modal #item-form:not(:has(#item-str)):not(:has(#item-base-ac)) input[type="file"],
.modal.trading-card-modal #item-form:not(:has(#item-str)):not(:has(#item-base-ac)) select,
.modal.trading-card-modal #item-form:not(:has(#item-str)):not(:has(#item-base-ac)) textarea {
    width: 100%;
    padding: 11px 12px;
    font-size: 14px;
}

.modal.trading-card-modal #item-form:not(:has(#item-str)):not(:has(#item-base-ac)) textarea {
    min-height: 96px;
    line-height: 1.5;
}

/* The rows that pair a control with an Add button (starting equipment, class
   features, spells by level) — same height, aligned to the bottom of the row. */
.modal.trading-card-modal #item-form:not(:has(#item-str)) .form-group div[style*="flex"] > .btn {
    align-self: stretch;
    white-space: nowrap;
}

/* Sub-lists inside a group (equipment added so far, features, spell levels)
   read as part of their field rather than as loose rows under it. */
.modal.trading-card-modal #item-form:not(:has(#item-str)) #equipment-list:not(:empty),
.modal.trading-card-modal #item-form:not(:has(#item-str)) #features-list:not(:empty),
.modal.trading-card-modal #item-form:not(:has(#item-str)) #spells-by-level:not(:empty) {
    padding: 10px 12px;
    border: 1px solid var(--panel-60, rgba(255, 255, 255, 0.12));
    border-radius: 8px;
    background: rgba(0, 0, 0, 0.18);
}

/* The action row sits away from the last field, not against it. */
.modal.trading-card-modal .modal-content:not(:has(#item-str)) .form-action-row,
.modal.trading-card-modal .modal-content:not(:has(#item-str)) .modal-buttons {
    margin-top: 4px;
    gap: 12px;
}


/* components/_forms.css */
/**
 * Form Components
 * Consolidated form styles
 * 
 * Used by:
 * - All form-list pages (factions, shops, classes, races, features, backgrounds, geography)
 * - Story page modals
 * - Character/NPC detail modals
 * - All editing forms across the application
 * 
 * All forms should use these shared styles for consistency.
 */

.form-section {
    margin-bottom: 30px;
}

.form-section h3 {
    color: var(--secondary-color);
    margin-bottom: 15px;
    font-size: 1.2em;
}

.form-group {
    margin-bottom: 20px;
}

.form-group label {
    display: block;
    color: var(--text-light);
    margin-bottom: 8px;
    font-weight: 600;
}

.form-group .required {
    color: var(--accent-color);
}

.form-group input[type="text"],
.form-group input[type="password"],
.form-group input[type="email"],
.form-group input[type="number"],
.form-group input[type="search"],
.form-group select,
.form-group textarea {
    width: 100%;
    padding: 12px;
    background: rgba(0, 0, 0, 0.3);
    border: 2px solid var(--border-color);
    border-radius: 8px;
    color: var(--text-light);
    font-size: 14px;
    font-family: inherit;
    transition: border-color 0.3s ease;
}

.form-group input[type="text"]:focus,
.form-group input[type="password"]:focus,
.form-group input[type="email"]:focus,
.form-group input[type="number"]:focus,
.form-group input[type="search"]:focus,
.form-group select:focus,
.form-group textarea:focus {
    outline: none;
    border-color: var(--primary-color);
}

.form-group textarea {
    resize: vertical;
    min-height: 80px;
}

.form-group small {
    display: block;
    color: var(--text-dim);
    font-size: 0.85em;
    margin-top: 5px;
}

.form-label {
    display: block;
    margin-bottom: 8px;
    font-weight: 600;
    color: var(--text-light);
}

.form-helper {
    font-size: 0.85em;
    color: var(--text-dim);
    margin-top: 4px;
}

.form-switch {
    display: flex;
    align-items: center;
    gap: 10px;
}

.form-switch input[type="checkbox"] {
    width: auto;
}

.form-switch span {
    color: var(--text-light);
}

.form-action-row {
    display: flex;
    gap: 10px;
    justify-content: flex-end;
    margin-top: 20px;
}

.form-action-row .btn {
    min-width: 100px;
}

.modal-inline-actions {
    display: flex;
    gap: 10px;
    margin-top: 15px;
}

.modal-inline-actions .btn {
    flex: 1;
}

/* Form Instructions and Helpers */
.instructions-section {
    background: rgba(0, 0, 0, 0.3);
    padding: 20px;
    border-radius: 8px;
    border: 1px solid var(--border-color);
    margin-bottom: 30px;
}

.instructions-section h3 {
    color: var(--primary-color);
    margin-bottom: 15px;
}

.setup-steps {
    margin-left: 20px;
    color: var(--text-light);
}

.setup-steps li {
    margin-bottom: 15px;
    line-height: 1.6;
}

.setup-steps li strong {
    color: var(--primary-color);
}

.setup-steps ul {
    margin-top: 8px;
    margin-left: 20px;
    list-style-type: disc;
}

.setup-steps code {
    background: rgba(0, 0, 0, 0.4);
    padding: 3px 8px;
    border-radius: 4px;
    color: var(--primary-color);
    font-family: 'Courier New', monospace;
    font-size: 0.9em;
}

.info-text {
    color: var(--text-light);
    margin-bottom: 12px;
    line-height: 1.6;
}

.feature-list {
    list-style: none;
    margin: 15px 0;
    padding-left: 0;
}

.feature-list li {
    color: var(--text-light);
    padding: 8px 0;
    line-height: 1.6;
}

.simple-steps {
    margin-left: 20px;
    color: var(--text-light);
    margin-top: 10px;
}

.simple-steps li {
    padding: 6px 0;
    line-height: 1.6;
}


/* components/_cards.css */
/**
 * Card Components
 * Item cards, detail cards, and card-related styles
 * 
 * Used by:
 * - Items page (with type-specific variants)
 * - Form-list pages (factions, shops, classes, etc.) - via pages/_form-list-pages.css
 * - Geography page - via pages/_form-list-pages.css
 * - Character/NPC detail pages - when displaying items in modals
 * 
 * All item cards across the app should use these base styles for consistency.
 */

/* Base Item Card */
.item-card {
    background: var(--panel-75);
    backdrop-filter: blur(10px);
    border-radius: 6px;
    border-left: 2px solid var(--primary-color);
    padding: 8px;
    cursor: grab;
    transition: all 0.3s ease;
    position: relative;
    width: 100%; /* Full width cards */
}

.item-card.spell {
    border-left-color: var(--primary-color, var(--abyssal-glow));
}

.item-card.weapon {
    border-left-color: var(--category-weapon);
}

.item-card.armor {
    border-left-color: var(--category-armor);
}

.item-card.consumable {
    border-left-color: var(--category-consumable);
}

.item-card:hover {
    transform: translateY(-3px);
    box-shadow: 0 4px 20px var(--shadow-primary-35);
}

.item-card.dragging {
    opacity: 0.5;
    cursor: grabbing;
}

.item-name {
    color: var(--primary-color, var(--abyssal-glow));
    font-size: 0.9em;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.item-type-badge {
    padding: 4px 10px;
    border-radius: 12px;
    font-size: 0.75em;
    font-weight: 600;
    text-transform: uppercase;
}

.weapon .item-type-badge {
    background: var(--category-weapon-bg);
    color: var(--category-weapon);
}

.armor .item-type-badge {
    background: var(--category-armor-bg);
    color: var(--category-armor);
}

.consumable .item-type-badge {
    background: var(--category-consumable-bg);
    color: var(--category-consumable);
}

.spell .item-type-badge {
    background: var(--accent-primary-20);
    color: var(--primary-color);
}

.item-details {
    font-size: 0.9em;
    color: var(--text-light, var(--abyssal-light));
    margin-top: 8px;
}

.item-details .item-meta-line {
    margin-bottom: 4px;
}

.item-description {
    margin-top: 8px;
    opacity: 0.8;
    line-height: 1.4;
}

/* Form List Items (used across multiple pages) */
.form-list-item {
    background: var(--panel-75);
    backdrop-filter: blur(10px);
    border-radius: 6px;
    border-left: 2px solid var(--primary-color);
    padding: 12px;
    margin-bottom: 12px;
    transition: all 0.3s ease;
}

.form-list-item:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 15px var(--shadow-primary-35);
    border-left-color: var(--secondary-color);
}

.form-list-item-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 8px;
}

.form-list-item-title {
    color: var(--primary-color);
    font-size: 1.1em;
    font-weight: 600;
}

.form-list-item-actions {
    display: flex;
    gap: 8px;
}

.form-list-item-content {
    color: var(--text-light);
    font-size: 0.9em;
    line-height: 1.5;
}

.form-list-item-meta {
    margin-top: 8px;
    font-size: 0.85em;
    color: var(--text-dim);
}


/* components/_details.css */
/**
 * Detail View Components
 * Styles for detail pages and detail modals
 */

.detail-header {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 30px;
    margin-bottom: 30px;
}

.detail-image {
    width: 200px;
    height: 200px;
    object-fit: cover;
    border-radius: 12px;
    border: 3px solid var(--secondary-color);
    box-shadow: 0 4px 20px var(--shadow-primary-35);
}

.detail-info {
    display: flex;
    flex-direction: column;
}

.detail-badge-container {
    margin-bottom: 15px;
}

.detail-info-line {
    margin-bottom: 10px;
    font-size: 1.1em;
}

.detail-info-line strong {
    color: var(--primary-color);
}

.detail-info-line span {
    color: var(--text-light);
}

.detail-section {
    margin-bottom: 25px;
}

.detail-section h3 {
    color: var(--primary-color);
    margin-bottom: 10px;
    font-size: 1.3em;
}

.detail-section-content {
    color: var(--text-light);
    line-height: 1.6;
    font-size: 1.05em;
    white-space: pre-wrap;
    word-wrap: break-word;
}

.detail-actions {
    margin-top: 30px;
    display: flex;
    gap: 10px;
    justify-content: flex-end;
}

.detail-content {
    max-height: 80vh;
    overflow-y: auto;
}

/* Shop Detail Items */
.detail-items-list {
    list-style: none;
    padding: 0;
    margin: 0;
}

.detail-item-entry {
    padding: 12px 15px;
    margin-bottom: 8px;
    background: var(--panel-40);
    border: 1px solid var(--panel-60);
    border-radius: 6px;
    border-left: 3px solid var(--primary-color);
}

.detail-item-entry-content {
    display: flex;
    justify-content: space-between;
    align-items: start;
}

.detail-item-entry-info {
    flex: 1;
}

.detail-item-entry-header {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 4px;
}

.detail-item-entry-name {
    color: var(--primary-color);
    font-size: 1.05em;
    font-weight: bold;
}

.detail-item-entry-type {
    color: var(--text-light);
    opacity: 0.7;
    font-size: 0.9em;
}

.detail-item-entry-notes {
    color: var(--text-light);
    font-size: 0.9em;
    margin-top: 4px;
    font-style: italic;
    opacity: 0.8;
}

.detail-item-entry-price {
    text-align: right;
    margin-left: 15px;
}

.detail-item-entry-price-value {
    color: var(--primary-color);
    font-weight: bold;
    font-size: 1.05em;
    white-space: nowrap;
}

.detail-item-entry-price-quantity {
    color: var(--text-light);
    font-size: 0.85em;
    margin-top: 2px;
}

.detail-item-entry-price .btn-small {
    margin-top: 8px;
    white-space: nowrap;
    padding: 6px 12px;
    font-size: 0.85em;
}


/* components/_campaign-card.css */
/**
 * Campaign Card Component
 * Styles for campaign cards on the home page
 */

/* A book on a shelf, in a card: cover, then a caption under it.
   The card was a bare cover with no surface, which was fine until the summary
   needed somewhere to live that was not on top of the artwork. A quiet panel
   gives the text a place to sit and still lets the jacket be the object —
   the border only shows itself on hover. */
.campaign-card {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 12px;
    background: var(--panel-60);
    border: 1px solid transparent;
    border-radius: 12px;
    padding: 12px;
    cursor: pointer;
    box-sizing: border-box;
    transition: border-color .2s ease, background .2s ease;
}

.campaign-card:hover,
.campaign-card:focus-within {
    background: var(--panel-75);
    border-color: var(--abyssal-glow);
}

/* ---- the cover ---- */

.campaign-cover {
    position: relative;
    display: flex;
    align-items: flex-end;
    /* The proportions of a hardback. Every cover is the same shape, which is
       what makes a shelf scannable. */
    aspect-ratio: 3 / 4;
    padding: 18px;
    border-radius: 10px;
    overflow: hidden;
    /* Hue comes from the title — see coverHue() in campaign-manager/ui.js — so
       a campaign is the same colour every time you come back to it. */
    /* Saturation and lightness come from the binding now, not from constants —
       see BINDINGS in js/utils/monogram.js. They step down in lightness rather
       than around the wheel, so the shelf still reads as distinct bindings to
       someone who cannot separate the hues. The fall to the foot of the cover
       is 9%, enough to look like a curved spine without sending the darkest
       binding to black. */
    background:
        linear-gradient(160deg,
            hsl(var(--campaign-hue, 210) var(--campaign-sat, 42%) var(--campaign-light, 32%)) 0%,
            hsl(calc(var(--campaign-hue, 210) + 10)
                calc(var(--campaign-sat, 42%) + 4%)
                calc(var(--campaign-light, 32%) - 9%)) 100%);
    box-shadow:
        0 10px 22px rgba(0, 0, 0, 0.38),
        inset 0 1px 0 rgba(255, 255, 255, 0.12);
    transition: transform .25s cubic-bezier(.4, 0, .2, 1), box-shadow .25s ease;
}

/* The spine, so it reads as a book rather than a swatch. */
.campaign-cover::before {
    content: '';
    position: absolute;
    inset: 0 auto 0 0;
    width: 9px;
    background: linear-gradient(90deg, rgba(0, 0, 0, 0.42), rgba(255, 255, 255, 0.06));
}

.campaign-card:hover .campaign-cover {
    transform: translateY(-5px);
    box-shadow:
        0 16px 30px rgba(0, 0, 0, 0.46),
        inset 0 1px 0 rgba(255, 255, 255, 0.16);
}

.campaign-cover-art {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* The fallback jacket, for a campaign with no cover image: the title set in the
   middle inside a ruled frame, the way a plain hardback prints one. It has to
   look chosen rather than left over, because most campaigns will never have
   artwork. */
.campaign-cover:not(:has(.campaign-cover-art)) {
    align-items: center;
    justify-content: center;
    text-align: center;
}

.campaign-cover:not(:has(.campaign-cover-art))::after {
    content: '';
    position: absolute;
    inset: 12px 12px 12px 18px;
    border: 1px solid rgba(255, 255, 255, 0.22);
    border-radius: 4px;
    pointer-events: none;
}

.campaign-cover .campaign-cover-title {
    position: relative;
    z-index: 1;
    padding: 0 6px;
    color: #fff;
    font-size: 1.05rem;
    font-weight: 700;
    line-height: 1.3;
    letter-spacing: 0.01em;
    text-shadow: 0 2px 10px rgba(0, 0, 0, 0.55);
    /* Long titles get four lines and then stop, so covers stay the same shape. */
    display: -webkit-box;
    -webkit-line-clamp: 4;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* The description is a blurb on the back of the jacket: there on hover, not
   competing with the shelf. */
/* Two classes deep on purpose: the blurb is a <p>, and `.home-page p` sets
   opacity 0.9, which outranks a single class and left it permanently visible
   over the cover. */
/* The summary, under the cover rather than over it.
   As an overlay this sat across the whole jacket at 0.82rem, centred, with the
   cover's own title visible through the gradient behind it — two pieces of text
   in the same place. Three lines under the caption say as much as anyone reads
   on a shelf, and the card stays the same height whether a campaign has a
   description or not. */
.campaign-blurb {
    margin: 4px 0 0;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
    color: var(--abyssal-light);
    opacity: 0.72;
    font-size: 0.78rem;
    line-height: 1.45;
    min-height: calc(3 * 1.45 * 0.78rem);
}

/* The panel decorations — top accent bar, hover wash, glow border — went
   with the panel. The cover is the object now, and it lifts on hover. */

/* Actions sit on the cover and appear on hover, the way they do on a media
   tile. Below the caption they took as much room as the cover itself and were
   on screen for every campaign at once, which is a lot of buttons for a shelf.
   They stay reachable by keyboard: focus inside the card reveals them. */
/* Actions in the card's footer, named, and on screen.
   They used to sit over the cover's top-right corner as two 29x25 icon
   buttons at opacity 0 until hover — hidden, tiny, and labelled only by a
   rune. "Where are the buttons" is the correct response to that. They are
   text now, and they are visible: a row of small quiet buttons under the
   caption costs less than a control nobody can find. */
.campaign-card-actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 6px;
    margin-top: auto;
    padding-top: 10px;
}

/* The buttons no longer appear on hover — they are always there. What hover
   does is bring them forward from the quiet state they sit in, so a shelf of
   campaigns does not read as a wall of controls. */
.campaign-card:hover .campaign-card-actions .btn,
.campaign-card:focus-within .campaign-card-actions .btn {
    opacity: 1;
}

.campaign-card-actions .btn {
    padding: 4px 10px;
    font-size: 0.72rem;
    background: var(--panel-75);
    border: 1px solid var(--abyssal-glow);
    border-radius: 6px;
    opacity: 0.75;
    transition: opacity .18s ease, background .18s ease;
}

.campaign-card-actions .btn:hover {
    opacity: 1;
    background: var(--surface-overlay);
}

.action-icon-btn {
    padding: 10px 14px;
    background: color-mix(in srgb, var(--primary-color) 15%, transparent 85%);
    border: 1px solid color-mix(in srgb, var(--primary-color) 40%, transparent 60%);
    border-radius: 8px;
    color: var(--primary-color);
    cursor: pointer;
    font-size: 16px;
    transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 40px;
    height: 40px;
    backdrop-filter: blur(4px);
}

.action-icon-btn:hover {
    background: color-mix(in srgb, var(--primary-color) 25%, transparent 75%);
    border-color: color-mix(in srgb, var(--primary-color) 60%, transparent 40%);
    transform: translateY(-2px);
    box-shadow: 0 4px 12px color-mix(in srgb, var(--primary-color) 20%, transparent 80%);
}

.action-icon-btn:active {
    transform: translateY(0);
}

.action-icon-btn.delete-btn,
.action-icon-btn.delete-rune {
    background: color-mix(in srgb, #EC4899 15%, transparent 85%);
    border-color: color-mix(in srgb, #EC4899 40%, transparent 60%);
    color: #EC4899;
}

.action-icon-btn.delete-btn:hover,
.action-icon-btn.delete-rune:hover {
    background: color-mix(in srgb, #EC4899 25%, transparent 75%);
    border-color: color-mix(in srgb, #EC4899 60%, transparent 40%);
    box-shadow: 0 4px 12px color-mix(in srgb, #EC4899 20%, transparent 80%);
}

.action-icon-btn .rune-icon {
    width: 18px;
    height: 18px;
}

/* ---- the caption under the cover ---- */

/* A caption, not a headline. At 1.65em with a glow it competed with the page
   title and pushed every card taller than its cover. */
.campaign-title {
    font-size: 0.98rem;
    color: var(--text-light);
    margin: 0;
    font-weight: 600;
    line-height: 1.35;
    letter-spacing: -0.01em;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.campaign-title-input {
    font-size: 1.8em;
    color: var(--primary-color);
    margin-bottom: 12px;
    font-weight: 700;
    background: transparent;
    border: none;
    border-bottom: 2px solid transparent;
    padding: 0 5px;
    width: 100%;
    transition: border-color 0.3s ease;
}

.campaign-title-input:focus {
    outline: none;
    border-bottom-color: var(--primary-color);
}

.campaign-main-content {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
}

.campaign-author {
    font-size: 0.82rem;
    color: var(--text-dim);
    margin: 0;
    font-weight: 400;
    opacity: 0.85;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* The description moved onto the cover as a blurb, revealed on hover. */
.campaign-description {
    display: none;
}

.campaign-meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 8px;
    margin: 2px 0 0;
    padding: 0;
    border: none;
    font-size: 0.74rem;
    color: var(--text-dim);
    opacity: 0.7;
}

.campaign-meta-item {
    display: flex;
    align-items: center;
    gap: 6px;
    opacity: 0.8;
}

.campaign-meta-item svg {
    width: 14px;
    height: 14px;
    opacity: 0.7;
}

.campaign-role-badge {
    display: inline-flex;
    align-items: center;
    padding: 4px 10px;
    border-radius: 12px;
    font-size: 0.8em;
    font-weight: 600;
    background: color-mix(in srgb, var(--accent-color) 20%, transparent 80%);
    color: var(--accent-color);
    border: 1px solid color-mix(in srgb, var(--accent-color) 40%, transparent 60%);
    text-transform: capitalize;
}

/* Paid Campaign Badge */
.campaign-publisher-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: linear-gradient(135deg, rgba(255, 215, 0, 0.2), rgba(255, 165, 0, 0.2));
    border: 2px solid rgba(255, 215, 0, 0.6);
    border-radius: 6px;
    padding: 4px 10px;
    font-size: 0.85em;
    font-weight: 600;
    color: #FFD700;
    margin-bottom: 10px;
    white-space: nowrap;
    box-shadow: 0 2px 8px rgba(255, 215, 0, 0.2);
}

.campaign-publisher-badge i {
    font-size: 1.1em;
}

.campaign-protected-indicator {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    background: rgba(255, 69, 0, 0.15);
    border: 1px solid rgba(255, 69, 0, 0.5);
    border-radius: 4px;
    padding: 3px 8px;
    font-size: 0.8em;
    color: #FF8C00;
    margin-left: 8px;
}

.campaign-protected-indicator i {
    font-size: 0.9em;
}


/* components/_form-list-items.css */
/**
 * Form List Items - Shared Styles
 * Used by ALL form-list pages: characters, factions, shops, classes, races, features, backgrounds, geography, maps, pantheon
 * 
 * These are the list item styles (not the card styles - those are in _cards.css)
 * Form-list-items are the items in the list view, form-list-cards are the grid card view
 */

/* Shared form-list container */
.characters-page .form-list-container,
.factions-page .form-list-container,
.shops-page .form-list-container,
.classes-page .form-list-container,
.races-page .form-list-container,
.features-page .form-list-container,
.backgrounds-page .form-list-container,
.items-page .form-list-container,
.geography-page .form-list-container,
.maps-page .form-list-container,
.pantheon-page .form-list-container {
    background: color-mix(in srgb, var(--theme-color-2, var(--abyssal-dark)) 20%, transparent);
    border-radius: 6px;
    border: 1px solid var(--primary-color, var(--abyssal-glow));
    overflow: hidden;
}

.geography-page .form-list-container,
.maps-page .form-list-container {
    width: 100%;
}

/* Shared form-list-item styles */
.characters-page .form-list-item,
.factions-page .form-list-item,
.shops-page .form-list-item,
.classes-page .form-list-item,
.races-page .form-list-item,
.features-page .form-list-item,
.backgrounds-page .form-list-item,
.items-page .form-list-item,
.geography-page .form-list-item,
.maps-page .form-list-item,
.pantheon-page .form-list-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 12px;
    cursor: pointer;
    border-bottom: 1px solid rgba(76, 211, 194, 0.2);
    background: transparent;
    width: 100%; /* Full width items */
}

.geography-page .form-list-item,
.maps-page .form-list-item,
.pantheon-page .form-list-item {
    transition: all 0.3s ease;
}

.characters-page .form-list-item,
.factions-page .form-list-item,
.shops-page .form-list-item,
.classes-page .form-list-item,
.races-page .form-list-item,
.features-page .form-list-item,
.backgrounds-page .form-list-item,
.items-page .form-list-item {
    transition: background 0.2s ease;
}

.characters-page .form-list-item:last-child,
.factions-page .form-list-item:last-child,
.shops-page .form-list-item:last-child,
.classes-page .form-list-item:last-child,
.races-page .form-list-item:last-child,
.features-page .form-list-item:last-child,
.backgrounds-page .form-list-item:last-child,
.items-page .form-list-item:last-child,
.geography-page .form-list-item:last-child,
.maps-page .form-list-item:last-child,
.pantheon-page .form-list-item:last-child {
    border-bottom: none;
}

.characters-page .form-list-item:hover,
.factions-page .form-list-item:hover,
.shops-page .form-list-item:hover,
.classes-page .form-list-item:hover,
.races-page .form-list-item:hover,
.features-page .form-list-item:hover,
.backgrounds-page .form-list-item:hover,
.items-page .form-list-item:hover {
    background: color-mix(in srgb, var(--theme-color-2, var(--abyssal-dark)) 40%, transparent);
}

.geography-page .form-list-item:hover,
.maps-page .form-list-item:hover,
.pantheon-page .form-list-item:hover {
    background: color-mix(in srgb, var(--theme-color-2, var(--abyssal-dark)) 40%, transparent);
    transform: translateY(-3px);
    box-shadow: 0 4px 20px color-mix(in srgb, var(--primary-color) 30%, transparent);
}

/* Shared form-list thumbnail styles */
.characters-page .form-list-thumbnail,
.factions-page .form-list-thumbnail,
.shops-page .form-list-thumbnail,
.classes-page .form-list-thumbnail,
.races-page .form-list-thumbnail,
.features-page .form-list-thumbnail,
.backgrounds-page .form-list-thumbnail,
.items-page .form-list-thumbnail,
.geography-page .form-list-thumbnail,
.maps-page .form-list-thumbnail,
.pantheon-page .form-list-thumbnail {
    flex-shrink: 0;
}

/* Standard thumbnail size (60px) */
.characters-page .form-list-thumbnail img,
.characters-page .form-list-thumbnail-img,
.factions-page .form-list-thumbnail img,
.factions-page .form-list-thumbnail-img,
.shops-page .form-list-thumbnail img,
.shops-page .form-list-thumbnail-img,
.classes-page .form-list-thumbnail img,
.classes-page .form-list-thumbnail-img,
.races-page .form-list-thumbnail img,
.races-page .form-list-thumbnail-img,
.features-page .form-list-thumbnail img,
.features-page .form-list-thumbnail-img,
.backgrounds-page .form-list-thumbnail img,
.backgrounds-page .form-list-thumbnail-img,
.items-page .form-list-thumbnail img,
.items-page .form-list-thumbnail-img,
.shops-page .form-list-thumbnail img,
.shops-page .form-list-thumbnail-img {
    width: 60px;
    height: 60px;
    object-fit: contain;
    border-radius: 4px;
    border: 1px solid var(--primary-color, var(--abyssal-glow));
    opacity: 0;
    transition: opacity 0.3s ease;
    background: color-mix(in srgb, var(--theme-color-2, var(--abyssal-dark)) 30%, transparent);
}

/* Larger thumbnail size (120px) for geography/maps/pantheon */
.geography-page .form-list-thumbnail img,
.geography-page .form-list-thumbnail-img,
.maps-page .form-list-thumbnail img,
.maps-page .form-list-thumbnail-img,
.pantheon-page .form-list-thumbnail img,
.pantheon-page .form-list-thumbnail-img {
    width: 120px;
    height: 120px;
    object-fit: contain;
    border-radius: 4px;
    border: 1px solid var(--primary-color, var(--abyssal-glow));
    opacity: 0;
    transition: opacity 0.3s ease;
    background: color-mix(in srgb, var(--theme-color-2, var(--abyssal-dark)) 30%, transparent);
}

.characters-page .form-list-thumbnail img.loaded,
.characters-page .form-list-thumbnail-img.loaded,
.factions-page .form-list-thumbnail img.loaded,
.factions-page .form-list-thumbnail-img.loaded,
.shops-page .form-list-thumbnail img.loaded,
.shops-page .form-list-thumbnail-img.loaded,
.classes-page .form-list-thumbnail img.loaded,
.classes-page .form-list-thumbnail-img.loaded,
.races-page .form-list-thumbnail img.loaded,
.races-page .form-list-thumbnail-img.loaded,
.features-page .form-list-thumbnail img.loaded,
.features-page .form-list-thumbnail-img.loaded,
.backgrounds-page .form-list-thumbnail img.loaded,
.backgrounds-page .form-list-thumbnail-img.loaded,
.items-page .form-list-thumbnail img.loaded,
.items-page .form-list-thumbnail-img.loaded,
.geography-page .form-list-thumbnail img.loaded,
.geography-page .form-list-thumbnail-img.loaded,
.maps-page .form-list-thumbnail img.loaded,
.maps-page .form-list-thumbnail-img.loaded,
.pantheon-page .form-list-thumbnail img.loaded,
.pantheon-page .form-list-thumbnail-img.loaded {
    opacity: 1;
}

/* Standard no-image placeholder (60px) */
.characters-page .form-list-thumbnail .no-image,
.factions-page .form-list-thumbnail .no-image,
.shops-page .form-list-thumbnail .no-image,
.classes-page .form-list-thumbnail .no-image,
.races-page .form-list-thumbnail .no-image,
.features-page .form-list-thumbnail .no-image,
.backgrounds-page .form-list-thumbnail .no-image,
.items-page .form-list-thumbnail .no-image {
    width: 60px;
    height: 60px;
    border-radius: 4px;
    border: 1px solid var(--primary-color, var(--abyssal-glow));
    background: color-mix(in srgb, var(--theme-color-2, var(--abyssal-dark)) 30%, transparent);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-light, var(--abyssal-light));
    opacity: 0.4;
    font-size: 0.7em;
}

/* Larger no-image placeholder (120px) */
.geography-page .form-list-thumbnail .no-image,
.maps-page .form-list-thumbnail .no-image,
.pantheon-page .form-list-thumbnail .no-image {
    width: 120px;
    height: 120px;
    border-radius: 4px;
    border: 1px solid var(--primary-color, var(--abyssal-glow));
    background: color-mix(in srgb, var(--theme-color-2, var(--abyssal-dark)) 30%, transparent);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-light, var(--abyssal-light));
    opacity: 0.4;
    font-size: 0.7em;
}

/* Shared form-list content styles */
.characters-page .form-list-content,
.factions-page .form-list-content,
.shops-page .form-list-content,
.classes-page .form-list-content,
.races-page .form-list-content,
.features-page .form-list-content,
.backgrounds-page .form-list-content,
.items-page .form-list-content,
.geography-page .form-list-content,
.maps-page .form-list-content,
.pantheon-page .form-list-content {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.characters-page .form-list-header,
.factions-page .form-list-header,
.shops-page .form-list-header,
.classes-page .form-list-header,
.races-page .form-list-header,
.features-page .form-list-header,
.backgrounds-page .form-list-header,
.items-page .form-list-header,
.geography-page .form-list-header,
.maps-page .form-list-header,
.pantheon-page .form-list-header {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.characters-page .form-list-name,
.factions-page .form-list-name,
.shops-page .form-list-name,
.classes-page .form-list-name,
.races-page .form-list-name,
.features-page .form-list-name,
.backgrounds-page .form-list-name,
.items-page .form-list-name,
.geography-page .form-list-name,
.maps-page .form-list-name,
.pantheon-page .form-list-name {
    font-size: 0.95em;
    font-weight: 600;
    color: var(--primary-color, var(--abyssal-glow));
}

.characters-page .form-list-badge,
.factions-page .form-list-badge,
.shops-page .form-list-badge,
.classes-page .form-list-badge,
.races-page .form-list-badge,
.features-page .form-list-badge,
.backgrounds-page .form-list-badge,
.items-page .form-list-badge,
.geography-page .form-list-badge,
.maps-page .form-list-badge,
.pantheon-page .form-list-badge {
    font-size: 0.7em;
    padding: 2px 8px;
}

.characters-page .form-list-summary,
.factions-page .form-list-summary,
.shops-page .form-list-summary,
.classes-page .form-list-summary,
.races-page .form-list-summary,
.features-page .form-list-summary,
.backgrounds-page .form-list-summary,
.items-page .form-list-summary,
.geography-page .form-list-summary,
.maps-page .form-list-summary,
.pantheon-page .form-list-summary {
    font-size: 0.75em;
    color: var(--text-light, var(--abyssal-light));
    opacity: 0.7;
}

.characters-page .form-list-description,
.factions-page .form-list-description,
.shops-page .form-list-description,
.classes-page .form-list-description,
.races-page .form-list-description,
.features-page .form-list-description,
.backgrounds-page .form-list-description,
.items-page .form-list-description,
.geography-page .form-list-description,
.maps-page .form-list-description,
.pantheon-page .form-list-description {
    font-size: 0.8em;
    color: var(--text-light, var(--abyssal-light));
    opacity: 0.8;
    line-height: 1.3;
}

.characters-page .form-list-meta,
.factions-page .form-list-meta,
.shops-page .form-list-meta,
.classes-page .form-list-meta,
.races-page .form-list-meta,
.features-page .form-list-meta,
.backgrounds-page .form-list-meta,
.items-page .form-list-meta,
.geography-page .form-list-meta,
.maps-page .form-list-meta,
.pantheon-page .form-list-meta {
    display: flex;
    gap: 8px;
    font-size: 0.7em;
    color: var(--text-light, var(--abyssal-light));
    opacity: 0.6;
}

.characters-page .form-list-actions,
.factions-page .form-list-actions,
.shops-page .form-list-actions,
.classes-page .form-list-actions,
.races-page .form-list-actions,
.features-page .form-list-actions,
.backgrounds-page .form-list-actions,
.items-page .form-list-actions,
.geography-page .form-list-actions,
.maps-page .form-list-actions,
.pantheon-page .form-list-actions {
    display: flex;
    gap: 4px;
}

.characters-page .form-list-actions button,
.factions-page .form-list-actions button,
.shops-page .form-list-actions button,
.classes-page .form-list-actions button,
.races-page .form-list-actions button,
.features-page .form-list-actions button,
.backgrounds-page .form-list-actions button,
.items-page .form-list-actions button,
.geography-page .form-list-actions button,
.maps-page .form-list-actions button,
.pantheon-page .form-list-actions button {
    padding: 4px 8px;
    font-size: 0.75em;
}

.characters-page .form-list-actions .icon-img,
.factions-page .form-list-actions .icon-img,
.shops-page .form-list-actions .icon-img,
.classes-page .form-list-actions .icon-img,
.races-page .form-list-actions .icon-img,
.features-page .form-list-actions .icon-img,
.backgrounds-page .form-list-actions .icon-img,
.items-page .form-list-actions .icon-img,
.geography-page .form-list-actions .icon-img,
.maps-page .form-list-actions .icon-img,
.pantheon-page .form-list-actions .icon-img {
    width: 14px;
    height: 14px;
}

/* Geography/Maps hierarchical children */
.geography-page .form-list-item + .form-list-children,
.maps-page .form-list-item + .form-list-children {
    display: block;
    width: 100%;
}

.geography-page .form-list-children,
.maps-page .form-list-children {
    display: block;
    width: 100%;
    padding-left: 0;
    border-left: 2px solid rgba(76, 211, 194, 0.2);
    margin-top: 0;
    margin-bottom: 0;
}

.geography-page .form-list-children.collapsed,
.maps-page .form-list-children.collapsed {
    display: none;
}

.geography-page .form-list-item[data-world-card] .form-list-content {
    flex: 1;
}

.geography-page .location-empty,
.maps-page .location-empty {
    padding: 20px;
    text-align: center;
    color: var(--text-light, var(--abyssal-light));
    opacity: 0.6;
}

.geography-page .location-empty.text-muted,
.maps-page .location-empty.text-muted {
    padding: 10px;
    margin-left: 20px;
}

.geography-page .form-list-expand-toggle,
.maps-page .form-list-expand-toggle {
    margin-left: auto;
    padding: 4px 8px;
    background: transparent;
    border: 1px solid var(--primary-color, var(--abyssal-glow));
    border-radius: 4px;
    color: var(--primary-color, var(--abyssal-glow));
    cursor: pointer;
    font-size: 0.9em;
    min-width: 28px;
}

.geography-page .form-list-expand-toggle:hover,
.maps-page .form-list-expand-toggle:hover {
    background: color-mix(in srgb, var(--theme-color-2, var(--abyssal-dark)) 40%, transparent);
}

/* Pantheon page carousel styles */
.pantheon-page .carousel-nav-btn {
    transition: background 0.2s ease, transform 0.2s ease;
}

.pantheon-page .carousel-nav-btn:hover {
    background: rgba(0, 0, 0, 0.7) !important;
    transform: translateY(-50%) scale(1.1);
}

.pantheon-page .carousel-nav-btn:active {
    transform: translateY(-50%) scale(0.95);
}

.pantheon-page .carousel-indicator {
    transition: background 0.2s ease, transform 0.2s ease;
}

.pantheon-page .carousel-indicator:hover {
    transform: scale(1.2);
}


/* components/_settings-menu.css */
/**
 * Settings Menu Component
 * Dropdown settings menu used across pages
 */

.settings-menu-container {
    position: relative;
    display: inline-block;
}

.settings-menu-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    padding: 0;
    background: transparent;
    border: none;
    border-radius: 8px;
    color: var(--primary-color);
    cursor: pointer;
    transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

.settings-menu-btn:hover {
    background: color-mix(in srgb, var(--primary-color) 10%, transparent);
    transform: translateY(-1px);
}

.settings-menu-btn:active {
    transform: translateY(0);
    background: color-mix(in srgb, var(--primary-color) 15%, transparent);
}

.settings-icon {
    width: 18px;
    height: 18px;
    stroke-width: 1.8;
}

.settings-menu {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    min-width: 200px;
    background: color-mix(in srgb, var(--surface-base) 98%, var(--accent-color) 2%);
    border: 1px solid color-mix(in srgb, var(--primary-color) 30%, transparent);
    border-radius: 6px;
    box-shadow: 0 4px 12px var(--shadow-ambient-30);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-8px);
    transition: all 0.2s ease;
    z-index: 10002;
    overflow: hidden;
}

.settings-menu-open {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}

.settings-menu-header {
    padding: 12px 16px;
    border-bottom: 1px solid color-mix(in srgb, var(--primary-color) 20%, transparent);
}

.settings-menu-header span {
    color: var(--primary-color);
    font-weight: 600;
    font-size: 0.85em;
}

.settings-menu-divider {
    height: 1px;
    background: color-mix(in srgb, var(--primary-color) 20%, transparent);
    margin: 4px 0;
}

.settings-menu-section {
    padding: 12px 16px;
}

.settings-menu-label {
    display: block;
    color: var(--text-light);
    font-size: 0.75em;
    font-weight: 500;
    margin-bottom: 8px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    opacity: 0.8;
}

.settings-menu-select {
    width: 100%;
    padding: 6px 10px;
    background: color-mix(in srgb, var(--surface-base) 95%, var(--accent-color) 5%);
    border: 1px solid color-mix(in srgb, var(--primary-color) 30%, transparent);
    border-radius: 4px;
    color: var(--text-light);
    font-size: 0.85em;
    cursor: pointer;
    transition: all 0.2s ease;
}

.settings-menu-select:hover {
    background: color-mix(in srgb, var(--surface-base) 98%, var(--accent-color) 2%);
    border-color: color-mix(in srgb, var(--primary-color) 40%, transparent);
}

.settings-menu-select:focus {
    outline: none;
    border-color: var(--primary-color);
    box-shadow: 0 0 8px color-mix(in srgb, var(--primary-color) 30%, transparent);
}


/* components/_account-menu.css */
/**
 * Account Menu Component
 * Dropdown account menu used in top banner
 */

/* CSS Variables for Account Menu */
:root {
    --menu-border-radius: 6px;
    --menu-transition: all 0.2s ease;
    --z-dropdown: 10002;
}

/* Animation Definitions */
@keyframes highlight-pulse {
    0%, 100% { 
        background: rgba(236, 72, 153, 0.1); 
    }
    50% { 
        background: rgba(236, 72, 153, 0.15); 
    }
}

@keyframes glow-pulse {
    0%, 100% { 
        opacity: 1; 
    }
    50% { 
        opacity: 0.6; 
    }
}

.account-menu-container {
    position: relative;
    display: inline-block;
}

.account-menu-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    padding: 0;
    background: transparent;
    border: none;
    border-radius: 8px;
    color: var(--primary-color);
    cursor: pointer;
    transition: var(--menu-transition);
    user-select: none;
    position: relative;             /* anchors .account-menu-badge */
}

/* Unread messages + friend requests waiting (S-52 FR-7, js/account-badge.js). */
.account-menu-badge {
    position: absolute;
    top: -2px;
    right: -4px;
    min-width: 17px;
    height: 17px;
    padding: 0 4px;
    border-radius: 9px;
    background: var(--danger-color, #e06c6c);
    color: #1a0b0b;
    font-size: 10px;
    font-weight: 700;
    line-height: 17px;
    text-align: center;
    pointer-events: none;
    box-shadow: 0 0 0 2px var(--surface-base, #0b1a2a);
}

.account-menu-badge[hidden] {
    display: none;
}

/* Browser compatibility fallback for color-mix() */
.account-menu-btn:hover {
    background: rgba(59, 130, 246, 0.1); /* fallback */
    background: color-mix(in srgb, var(--primary-color) 10%, transparent);
    transform: translateY(-1px);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.account-menu-btn:active {
    transform: translateY(0);
    background: rgba(59, 130, 246, 0.15); /* fallback */
    background: color-mix(in srgb, var(--primary-color) 15%, transparent);
}

/* Focus states for accessibility */
.account-menu-btn:focus-visible {
    outline: 2px solid var(--primary-color);
    outline-offset: 2px;
    background: rgba(59, 130, 246, 0.1); /* fallback */
    background: color-mix(in srgb, var(--primary-color) 10%, transparent);
}

.account-icon {
    width: 18px;
    height: 18px;
    stroke-width: 1.8;
}

.account-menu {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    min-width: 180px;
    background: var(--surface-base); /* fallback */
    background: color-mix(in srgb, var(--surface-base) 98%, var(--accent-color) 2%);
    border: 1px solid rgba(59, 130, 246, 0.3); /* fallback */
    border: 1px solid color-mix(in srgb, var(--primary-color) 30%, transparent);
    border-radius: var(--menu-border-radius);
    box-shadow: 0 4px 12px var(--shadow-ambient-30);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-8px);
    transition: var(--menu-transition);
    z-index: var(--z-dropdown);
    overflow: hidden;
    backdrop-filter: blur(10px);
    pointer-events: none; /* Prevent clicks while closed */
    will-change: auto; /* Optimize: only change when animating */
}

.account-menu-open {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
    pointer-events: auto; /* Enable clicks when open */
    will-change: opacity, transform; /* Optimize when animating */
}

.account-menu-header {
    padding: 12px 16px;
    border-bottom: 1px solid rgba(59, 130, 246, 0.2); /* fallback */
    border-bottom: 1px solid color-mix(in srgb, var(--primary-color) 20%, transparent);
}

.account-menu-username {
    color: var(--primary-color);
    font-weight: 600;
    font-size: 0.85em;
    text-transform: capitalize;
}

.account-menu-divider {
    height: 1px;
    background: rgba(59, 130, 246, 0.2); /* fallback */
    background: color-mix(in srgb, var(--primary-color) 20%, transparent);
    margin: 4px 0;
}

.account-menu-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
    padding: 10px 16px;
    background: transparent;
    border: none;
    color: var(--text-light);
    font-size: 0.8em;
    font-weight: 500;
    text-align: left;
    cursor: pointer;
    transition: var(--menu-transition);
    user-select: none;
}

.account-menu-item:hover {
    background: rgba(59, 130, 246, 0.15); /* fallback */
    background: color-mix(in srgb, var(--primary-color) 15%, transparent);
    color: var(--primary-color);
}

/* Focus states for accessibility */
.account-menu-item:focus-visible {
    outline: 2px solid var(--primary-color);
    outline-offset: -2px;
    background: rgba(59, 130, 246, 0.15); /* fallback */
    background: color-mix(in srgb, var(--primary-color) 15%, transparent);
}

.account-menu-item-danger {
    color: var(--danger-color, #EC4899);
}

.account-menu-item-danger:hover {
    background: rgba(236, 72, 153, 0.15); /* fallback */
    background: color-mix(in srgb, var(--danger-color, #EC4899) 15%, transparent);
    color: var(--danger-color, #EC4899);
}

.account-menu-item-danger:focus-visible {
    outline-color: var(--danger-color, #EC4899);
    background: rgba(236, 72, 153, 0.15); /* fallback */
    background: color-mix(in srgb, var(--danger-color, #EC4899) 15%, transparent);
}

.invitations-badge {
    display: inline-block;
    background: var(--accent-color, #EC4899);
    color: white;
    border-radius: 10px;
    padding: 2px 6px;
    font-size: 0.7em;
    font-weight: 600;
    min-width: 18px;
    text-align: center;
    margin-left: 8px;
}

.account-menu-item.has-pending-invitations {
    background: rgba(236, 72, 153, 0.1);
    border-left: 3px solid var(--accent-color, #EC4899);
    animation: highlight-pulse 2s ease-in-out infinite;
    position: relative;
}

.account-menu-item.has-pending-invitations::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 3px;
    background: var(--accent-color, #EC4899);
    animation: glow-pulse 2s ease-in-out infinite;
}

/* Mobile Responsiveness */
@media (max-width: 480px) {
    .account-menu {
        /* Full width on mobile for easier tapping */
        right: -8px;
        left: -8px;
        min-width: auto;
    }
    
    .account-menu-item {
        padding: 14px 16px; /* Larger touch targets */
    }
}

/* Performance: Remove backdrop-filter on mobile/touch devices */
@media (hover: none) {
    .account-menu {
        backdrop-filter: none;
        background: var(--surface-base); /* solid background instead */
    }
}

/* Accessibility: Respect reduced motion preference */
@media (prefers-reduced-motion: reduce) {
    .account-menu,
    .account-menu-btn,
    .account-menu-item {
        transition: none;
        animation: none;
    }
    
    .account-menu-item.has-pending-invitations,
    .account-menu-item.has-pending-invitations::before {
        animation: none;
    }
}

/* Browser compatibility: Fallback for browsers without color-mix() support */
@supports not (background: color-mix(in srgb, white 50%, black)) {
    .account-menu-btn:hover {
        background: rgba(59, 130, 246, 0.1);
    }
    
    .account-menu-btn:active {
        background: rgba(59, 130, 246, 0.15);
    }
    
    .account-menu-btn:focus-visible {
        background: rgba(59, 130, 246, 0.1);
    }
    
    .account-menu {
        background: var(--surface-base);
        border: 1px solid rgba(59, 130, 246, 0.3);
    }
    
    .account-menu-header {
        border-bottom: 1px solid rgba(59, 130, 246, 0.2);
    }
    
    .account-menu-divider {
        background: rgba(59, 130, 246, 0.2);
    }
    
    .account-menu-item:hover {
        background: rgba(59, 130, 246, 0.15);
    }
    
    .account-menu-item:focus-visible {
        background: rgba(59, 130, 246, 0.15);
    }
    
    .account-menu-item-danger:hover {
        background: rgba(236, 72, 153, 0.15);
    }
    
    .account-menu-item-danger:focus-visible {
        background: rgba(236, 72, 153, 0.15);
    }
}


/* components/_friends.css */
/* ============================================================================
   FRIENDS PANEL (S-51 FR-8)
   Shared by the home page and the campaign viewer. The list and a
   conversation swap places inside one modal; the conversation reuses the
   .dm-* thread styles from pages/_viewer.css, and this file supplies what the
   viewer scopes to .viewer-page so it also looks right on the home page.
   Colours come from the theme tokens so every palette stays readable.
   ============================================================================ */

.friends-modal .friends-modal-content {
    max-width: 520px;
    width: calc(100% - 32px);
}

.friends-add {
    display: flex;
    gap: 8px;
    margin: 4px 0 6px;
}

.friends-add-input {
    flex: 1;
    min-width: 0;
    padding: 9px 11px;
    border-radius: 6px;
    border: 1px solid var(--border-color);
    background: var(--surface-base);
    color: var(--text-light);
}

.friends-status {
    font-size: .86em;
    margin: 0 0 10px;
    color: color-mix(in srgb, var(--text-light) 70%, transparent);
}

.friends-status.is-error {
    color: var(--danger-color);
}

.friends-section {
    margin-bottom: 18px;
}

.friends-section-title {
    font-size: .72em;
    font-weight: bold;
    text-transform: uppercase;
    letter-spacing: .08em;
    color: color-mix(in srgb, var(--text-light) 65%, transparent);
    margin-bottom: 6px;
}

.friends-empty {
    color: color-mix(in srgb, var(--text-light) 65%, transparent);
    font-size: .9em;
    margin: 4px 0;
}

.friends-error {
    color: var(--danger-color);
}

.friend-row {
    border-bottom: 1px solid var(--border-color);
}

.friend-row-main {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 9px 4px;
}

.friend-row-name {
    flex: 1;
    min-width: 0;
}

.friend-row-name strong {
    display: block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.friend-row-sub {
    display: block;
    font-size: .8em;
    color: color-mix(in srgb, var(--text-light) 65%, transparent);
}

.friend-row-buttons {
    display: flex;
    gap: 6px;
    flex-shrink: 0;
}

/* Block / Report / Remove sit behind "More", out of the way of Message:
   they are for a bad moment, not the everyday. */
.friend-row-more {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 6px;
    padding: 0 4px 10px;
}

.friend-row-more[hidden] {
    display: none;
}

.friend-row-more .is-danger {
    border-color: var(--danger-color);
    color: var(--danger-color);
}

/* ---- A conversation inside the panel ---- */

.friends-conversation {
    height: min(60vh, 520px);
}

.friends-conversation[hidden] {
    display: none;
}

.friends-conversation .dm-thread-header {
    padding-right: 36px;           /* clear of the modal's close button */
}

.friends-conversation .chat-input-container {
    display: flex;
    gap: 8px;
    padding: 10px 0 0;
    border-top: 1px solid var(--border-color);
}

.friends-conversation .chat-input-container input {
    flex: 1;
    min-width: 0;
    padding: 9px 12px;
    border-radius: 6px;
    border: 1px solid var(--border-color);
    background: var(--surface-base);
    color: var(--text-light);
}

.friends-conversation .chat-send-btn {
    padding: 9px 16px;
    border: none;
    border-radius: 6px;
    background: var(--primary-color);
    color: var(--surface-base);
    font-weight: 600;
    cursor: pointer;
}


/* components/_app-bar.css */
/**
 * The application bar — home, marketplace and campaign viewer.
 *
 * The problem this replaces: `.nav-link` was never defined anywhere, so "Home"
 * and "My Purchases" rendered as bare anchors in the browser's default link
 * blue on a near-black bar and could not be read. Meanwhile "Campaign Store"
 * carried a permanent purple call-to-action pill, so it looked like the current
 * page on every page. One shouting link and two invisible ones, and no active
 * state at all.
 *
 * The scale here is deliberate: a resting link is clearly legible, hover lifts
 * it, and the current page is marked by a filled background plus an underline —
 * so it does not rely on colour alone.
 */

/* Pinned across the very top, over the sidebar rather than beside it. The bar
   belongs to the application, not to the page's content column — in normal
   flow it started after the sidebar and sat below the top edge, which read as
   a panel floating in the middle of the page. */
.app-bar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    /* Above the sidebar, which sits at 9999. */
    z-index: 10001;
    background: color-mix(in srgb, var(--surface-base) 96%, var(--accent-color) 4%);
    border-bottom: 1px solid color-mix(in srgb, var(--primary-color) 22%, transparent);
    backdrop-filter: blur(10px);
}

.app-bar-inner {
    display: flex;
    align-items: center;
    gap: 16px;
    /* The home page reveals the bar with `style.display = 'flex'`, left over
       from when the bar itself was the flex container. That makes this a flex
       *item*, which shrinks to its content and then centres itself on the
       margin below — the links ended up floating in the middle of the page.
       Claiming the full width works whether the parent is block or flex. */
    width: 100%;
    /* Matches whatever column the page underneath is using, so the links line
       up with the content they label instead of floating past its edge. The
       number lives in --page-max; this bar is shared by pages that legitimately
       want different widths (home is a wide board, the store is a shop). */
    max-width: var(--page-max);
    margin: 0 auto;
    /* Matches the page gutter, so the bar's text starts on the same line as the
       content beneath it rather than 4px inboard of it. */
    padding: 0 20px;
    min-height: 56px;
}

.app-bar-left {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-shrink: 0;
}

.app-bar-left:empty {
    display: none;
}

.app-bar-nav {
    display: flex;
    align-items: center;
    gap: 4px;
    flex: 1;
    min-width: 0;
    overflow-x: auto;
    scrollbar-width: none;
}

.app-bar-nav::-webkit-scrollbar {
    display: none;
}

.app-bar-right {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
    margin-left: auto;
}

.app-bar-status {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-right: 4px;
}

.app-bar-status:empty {
    display: none;
}

/* ---- links ---- */

/* `button` is in the selector deliberately: New Campaign and Import act on the
   page rather than navigating, so they are buttons — and a bare `button` picks
   up the browser's grey chrome, which rendered them as white boxes in the bar. */
.app-bar-link,
button.app-bar-link {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 14px;
    border: none;
    border-radius: 8px;
    background: none;
    color: rgba(255, 255, 255, 0.72);
    font-family: inherit;
    font-size: 0.92em;
    font-weight: 500;
    text-decoration: none;
    white-space: nowrap;
    cursor: pointer;
    transition: color .15s ease, background-color .15s ease;
}

.app-bar-link:hover {
    color: #fff;
    background: color-mix(in srgb, var(--primary-color) 16%, transparent);
}

.app-bar-link:focus-visible {
    outline: 2px solid var(--primary-color);
    outline-offset: 2px;
}

/* The current page. Background *and* an underline: colour alone is not a
   signal for everyone, and aria-current carries it to screen readers. */
.app-bar-link.is-current {
    color: #fff;
    font-weight: 600;
    background: color-mix(in srgb, var(--primary-color) 22%, transparent);
}

.app-bar-link.is-current::after {
    content: '';
    position: absolute;
    left: 14px;
    right: 14px;
    bottom: 3px;
    height: 2px;
    border-radius: 2px;
    background: var(--primary-color);
}

.app-bar-link[hidden] {
    display: none;
}

/* ---- left slot ---- */

.app-bar-back {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 13px;
    border: 1px solid color-mix(in srgb, var(--primary-color) 35%, transparent);
    border-radius: 8px;
    background: none;
    color: rgba(255, 255, 255, 0.8);
    font-size: 0.88em;
    cursor: pointer;
}

.app-bar-back:hover {
    color: #fff;
    background: color-mix(in srgb, var(--primary-color) 16%, transparent);
}

/* Branding. Not a link, so it is not focusable and does not compete with the
   navigation next to it. */
.app-bar-brandmark {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    flex-shrink: 0;
    margin-right: 8px;
    color: rgba(255, 255, 255, 0.92);
    font-weight: 600;
    font-size: 0.95em;
    letter-spacing: -0.01em;
    user-select: none;
}

.app-bar-brandmark img {
    width: 26px;
    height: 26px;
    border-radius: 5px;
}

/* The product name is the first thing to go when the bar runs out of room —
   the logo still identifies it, and the links matter more. */
@media (max-width: 900px) {
    .app-bar-brandmark span {
        display: none;
    }
}

/* ---- status slot (the viewer's campaign name and role) ---- */

.app-bar-campaign {
    color: rgba(255, 255, 255, 0.9);
    font-size: 0.86em;
    font-weight: 500;
    max-width: 260px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.app-bar-role {
    padding: 2px 8px;
    border-radius: 10px;
    background: color-mix(in srgb, var(--primary-color) 20%, transparent);
    color: rgba(255, 255, 255, 0.75);
    font-size: 0.72em;
    text-transform: capitalize;
}

/* On a narrow window the links scroll and the status text gets out of the way
   before the menus do — you can always reach your account. */
@media (max-width: 760px) {
    .app-bar-inner {
        padding: 0 12px;
        gap: 8px;
    }

    .app-bar-status {
        display: none;
    }

    .app-bar-link {
        padding: 8px 10px;
    }
}

/* ---- page header ----
   Title on the left, the actions that create things on the right. The ordinary
   shape of an application page header, and where people look for "new". */

.page-header {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 24px;
    flex-wrap: wrap;
}

.page-header-text {
    min-width: 0;
}

.page-header-actions {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-shrink: 0;
    /* Sits on the baseline of the heading block rather than floating above it. */
    padding-bottom: 6px;
}

/* The global .btn is sized for dense toolbars — 11px text in 4px of padding.
   Next to a 44px page heading that reads as an afterthought, so the header's
   own actions get a size that belongs beside a title. */
.page-header-actions .btn {
    padding: 10px 18px;
    font-size: 0.95rem;
    border-radius: 8px;
}

.page-header-actions .btn .rune-icon {
    width: 17px;
    height: 17px;
}

@media (max-width: 640px) {
    .page-header {
        align-items: stretch;
    }

    .page-header-actions {
        width: 100%;
    }

    .page-header-actions .btn {
        flex: 1;
        justify-content: center;
    }
}

/* ============================================================
   Narrow screens: one menu instead of a row that does not fit
   ============================================================
   .app-bar-nav is overflow-x: auto with its scrollbar hidden. On a desktop
   that is a tidy fallback nobody sees; at 375px it clipped "Marketplace"
   mid-word and put My Purchases past the right edge, reachable only by
   dragging sideways inside the bar with nothing to suggest it was there.
   Below the breakpoint the row is replaced outright, so the bar stays one
   line tall and no page's top padding has to change. */
.app-bar-menu-container {
    display: none;
    position: relative;
}

.app-bar-menu-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 12px;
    border: 1px solid color-mix(in srgb, var(--primary-color) 30%, transparent);
    border-radius: 8px;
    background: none;
    color: rgba(255, 255, 255, 0.9);
    font-family: inherit;
    font-size: 0.92em;
    font-weight: 500;
    cursor: pointer;
}

.app-bar-menu-btn svg {
    width: 18px;
    height: 18px;
}

.app-bar-menu-btn:focus-visible {
    outline: 2px solid var(--primary-color);
    outline-offset: 2px;
}

.app-bar-menu {
    display: none;
    position: absolute;
    top: calc(100% + 8px);
    left: 0;
    min-width: 220px;
    padding: 6px;
    border: 1px solid color-mix(in srgb, var(--primary-color) 28%, transparent);
    border-radius: 10px;
    background: var(--surface-base);
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
    z-index: 10002;
}

.app-bar-menu.is-open {
    display: block;
}

.app-bar-menu-item {
    display: flex;
    align-items: center;
    gap: 8px;
    width: 100%;
    padding: 10px 12px;
    border: none;
    border-radius: 6px;
    background: none;
    color: rgba(255, 255, 255, 0.85);
    font-family: inherit;
    font-size: 0.95em;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}

.app-bar-menu-item:hover {
    color: #fff;
    background: color-mix(in srgb, var(--primary-color) 16%, transparent);
}

.app-bar-menu-item.is-current {
    color: #fff;
    font-weight: 600;
    background: color-mix(in srgb, var(--primary-color) 22%, transparent);
}

.app-bar-menu-item[hidden] {
    display: none;
}

.app-bar .navigation-icon {
    width: 20px;
    height: 20px;
    flex-shrink: 0;
    color: #b8d9d5;
}

@media (max-width: 700px) {
    .app-bar-nav {
        display: none;
    }

    .app-bar-menu-container {
        display: block;
    }
}


/* utilities/_inputs.css */
/**
 * Input Utilities
 * Base styles for form inputs, selects, and textareas
 */

input[type="text"],
input[type="number"],
input[type="password"],
input[type="email"],
input[type="search"],
select,
textarea {
    background: var(--panel-40);
    border: 2px solid color-mix(in srgb, var(--border-color) 70%, transparent);
    color: var(--text-light);
    border-radius: 8px;
    padding: 10px 14px;
    font-family: inherit;
    font-size: 0.95rem;
    transition: border-color 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
    box-shadow: inset 0 1px 2px color-mix(in srgb, var(--shadow-color) 15%, transparent);
}

input[type="text"]::placeholder,
input[type="number"]::placeholder,
input[type="password"]::placeholder,
input[type="email"]::placeholder,
input[type="search"]::placeholder,
textarea::placeholder {
    color: var(--text-dim);
}

input[type="text"]:focus,
input[type="number"]:focus,
input[type="password"]:focus,
input[type="email"]:focus,
input[type="search"]:focus,
select:focus,
textarea:focus {
    outline: none;
    border-color: var(--primary-color);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary-color) 20%, transparent);
    background: color-mix(in srgb, var(--panel-40) 65%, var(--panel-60) 35%);
}

select {
    appearance: none;
    background-image: linear-gradient(45deg, transparent 50%, var(--primary-color) 50%), linear-gradient(135deg, var(--primary-color) 50%, transparent 50%);
    background-position: calc(100% - 20px) calc(50% - 6px), calc(100% - 12px) calc(50% - 6px), calc(100% - 1.2em) 50%;
    background-size: 8px 8px, 8px 8px;
    background-repeat: no-repeat;
    padding-right: 2.8rem;
}


/* utilities/_icons.css */
/**
 * Icon Utilities
 * Icon image styles and icon-related utilities
 */

/* Icon images (for PNG icons from images/icons/) */
.icon-img {
    display: inline-block;
    width: 24px;
    height: 24px;
    vertical-align: middle;
    object-fit: contain;
    filter: brightness(1.8);
}

.icon-img-sm {
    width: 20px;
    height: 20px;
}

.icon-img-md {
    width: 28px;
    height: 28px;
}

.icon-img-lg {
    width: 36px;
    height: 36px;
}

.btn .icon-img {
    width: 14px;
    height: 14px;
}

.btn-small .icon-img {
    width: 18px;
    height: 18px;
}

/* Runic Icon System */
.rune-icon {
    display: inline-block;
    width: 16px;
    height: 16px;
    vertical-align: middle;
    fill: currentColor;
    stroke: currentColor;
    filter: brightness(1.8);
}

.rune-icon-sm {
    width: 16px;
    height: 16px;
}

.rune-icon-md {
    width: 24px;
    height: 24px;
}

.rune-icon-lg {
    width: 20px;
    height: 20px;
}

/* Animated hover effects for runic icons */
.rune-icon-animated {
    transition: all 0.3s ease;
    filter: brightness(1.8) drop-shadow(0 0 2px currentColor);
}

.rune-icon-animated:hover {
    transform: scale(1.1);
    filter: brightness(2.0) drop-shadow(0 0 6px currentColor);
}

/* Icon button variations */
.icon-btn-rune {
    padding: 8px;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 4px;
    color: var(--abyssal-glow, #A855F7);
    cursor: pointer;
    transition: all 0.2s ease;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.icon-btn-rune:hover {
    background: rgba(168, 85, 247, 0.2);
    border-color: rgba(168, 85, 247, 0.4);
}

.icon-btn-rune.delete-rune {
    color: var(--abyssal-accent, #EC4899);
}

.icon-btn-rune.delete-rune:hover {
    background: rgba(236, 72, 153, 0.2);
    border-color: rgba(236, 72, 153, 0.4);
}


/* utilities/_viewer-mode.css */
/**
 * Viewer Mode Utilities
 * Styles for hiding edit/delete buttons when in viewer mode
 */



/* Viewer mode: Hide mutate actions — keep Print (and other read-only tools) visible */
body.viewer-mode .btn-edit,
body.viewer-mode .btn-delete,
body.viewer-mode .btn-add,
body.viewer-mode .btn-export,
body.viewer-mode .btn-import,
/* Hide buttons with "add" in onclick */
body.viewer-mode button[onclick*="add"],
body.viewer-mode button[onclick*="Add"],
body.viewer-mode button[onclick*="ADD"],
/* Hide buttons with "edit" in onclick */
body.viewer-mode button[onclick*="edit"],
body.viewer-mode button[onclick*="Edit"],
body.viewer-mode button[onclick*="EDIT"],
/* Hide buttons with "delete" in onclick */
body.viewer-mode button[onclick*="delete"],
body.viewer-mode button[onclick*="Delete"],
body.viewer-mode button[onclick*="DELETE"],
/* Hide buttons with "import" in onclick */
body.viewer-mode button[onclick*="import"],
body.viewer-mode button[onclick*="Import"],
body.viewer-mode button[onclick*="IMPORT"],
/* Hide buttons with "export" in onclick */
body.viewer-mode button[onclick*="export"],
body.viewer-mode button[onclick*="Export"],
body.viewer-mode button[onclick*="EXPORT"],
/* Hide buttons with "clear" in onclick.
   maps and tables wire Clear All through onclick rather than data-action, and
   only the data-action form was covered here. js/pages/maps.js used to hide its
   own Add and Clear buttons by hand for exactly that reason; this rule is what
   let that copy go. */
body.viewer-mode button[onclick*="clear"],
body.viewer-mode button[onclick*="Clear"],
body.viewer-mode button[onclick*="CLEAR"],
/* Hide buttons with "currency" in onclick */
body.viewer-mode button[onclick*="currency"],
body.viewer-mode button[onclick*="Currency"],
body.viewer-mode button[onclick*="CURRENCY"],
/* Hide buttons with these keywords in class names */
body.viewer-mode button[class*="add"],
body.viewer-mode button[class*="edit"],
body.viewer-mode button[class*="delete"],
body.viewer-mode button[class*="import"],
body.viewer-mode button[class*="export"],
body.viewer-mode button[class*="currency"],
/* Hide buttons with data-action attributes (new pattern) */
body.viewer-mode button[data-action="add-item"],
body.viewer-mode button[data-action="edit-item"],
body.viewer-mode button[data-action="delete-item"],
body.viewer-mode button[data-action="import-data"],
body.viewer-mode button[data-action="export-data"],
body.viewer-mode button[data-action="clear-all"],
body.viewer-mode button[data-action="load-defaults"] {
    display: none !important;
}

/* Explicitly keep print (and similar read-only actions) available to viewers */
body.viewer-mode button[data-action="print-items"] {
    display: inline-flex !important;
}

/* Hide action sections for viewers */
body.viewer-mode .item-actions,
body.viewer-mode .card-actions,
body.viewer-mode .form-list-actions {
    display: none !important;
}

/* Exception: Allow item-actions and form-list-actions containers on character-select page for viewers */
/* (so they can claim characters and join combat) */
body.viewer-mode.characters-page .item-actions,
body.characters-page.viewer-mode .item-actions,
body.viewer-mode .characters-page .item-actions,
body.viewer-mode.characters-page .form-list-actions,
body.characters-page.viewer-mode .form-list-actions,
body.viewer-mode .characters-page .form-list-actions {
    display: flex !important;
}

/* Ensure join combat and claim buttons are visible for viewers */
body.viewer-mode .characters-page .item-actions button.join-combat-btn,
body.viewer-mode .characters-page .form-list-actions button.join-combat-btn,
body.viewer-mode .characters-page .item-actions button[onclick*="joinCombat"],
body.viewer-mode .characters-page .form-list-actions button[onclick*="joinCombat"],
body.viewer-mode .characters-page .item-actions button[onclick*="claimCharacter"],
body.viewer-mode .characters-page .form-list-actions button[onclick*="claimCharacter"],
body.viewer-mode .characters-page .item-actions button[title="Join Combat"],
body.viewer-mode .characters-page .form-list-actions button[title="Join Combat"],
body.viewer-mode .characters-page .item-actions button[title="Claim Character"],
body.viewer-mode .characters-page .form-list-actions button[title="Claim Character"] {
    display: inline-flex !important;
    visibility: visible !important;
    opacity: 1 !important;
}

/* Ensure edit and delete buttons are visible for owners and DMs - override viewer-mode hiding */
body.viewer-mode .characters-page .item-actions button[onclick*="editItem"],
body.viewer-mode .characters-page .form-list-actions button[onclick*="editItem"],
body.viewer-mode .characters-page .item-actions button[onclick*="deleteItem"],
body.viewer-mode .characters-page .form-list-actions button[onclick*="deleteItem"],
body.viewer-mode .characters-page .item-actions button.btn-danger,
body.viewer-mode .characters-page .form-list-actions button.btn-danger {
    display: inline-flex !important;
    visibility: visible !important;
    opacity: 1 !important;
}

/* The roster renderer marks only the signed-in player's own character. */
body.viewer-mode.characters-page .form-list-actions button.owned-character-edit[data-action="edit-item"] {
    display: inline-flex !important;
    visibility: visible !important;
    opacity: 1 !important;
}


/* utilities/_empty-state.css */
/**
 * Empty State Utilities
 * Shared empty state styles across pages
 */

/*
 * Visible by default — which sounds obvious, and was the bug.
 *
 * This used to be `display: none` unless a `.show` class was added. One element
 * in the whole app works that way: #empty-state on the home page, which is in
 * the markup from the start and toggled by campaign-manager/ui.js. Every other
 * use injects this markup through innerHTML at the moment it wants it seen —
 * ten call sites across My Purchases, the creator dashboard, listings, maps and
 * the image library — and none of them added `.show`.
 *
 * So every one of them was invisible. My Purchases looked like it rendered
 * nothing at all; it was rendering "Error loading purchases. Please try again."
 * into a box the stylesheet had hidden. An empty state you cannot see is worse
 * than none, because the page looks broken and says nothing.
 *
 * The pre-rendered one keeps its old behaviour below, by id.
 */
.empty-state {
    display: block;
    text-align: center;
    padding: 80px 40px;
    color: var(--text-light);
    opacity: 0.75;
    background: linear-gradient(
        135deg,
        color-mix(in srgb, var(--surface-panel) 85%, transparent 15%) 0%,
        color-mix(in srgb, var(--panel-75) 90%, transparent 10%) 100%
    );
    border-radius: 16px;
    border: 1px solid color-mix(in srgb, var(--border-color) 40%, transparent 60%);
    backdrop-filter: blur(10px);
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
    margin: 40px auto;
    max-width: 600px;
}

/* The home page's empty state ships in the markup and is toggled, so it stays
   hidden until campaign-manager/ui.js decides there is nothing to list. */
#empty-state:not(.show) {
    display: none;
}

.empty-state h2 {
    color: var(--primary-color);
    margin-bottom: 16px;
    font-size: 1.75em;
    font-weight: 600;
    text-shadow: 0 0 8px color-mix(in srgb, var(--primary-color) 25%, transparent);
}

.empty-state p {
    color: var(--text-light);
    opacity: 0.85;
    line-height: 1.7;
    font-size: 1.05em;
    margin-bottom: 24px;
}

/* A link in an empty state is usually the way out of it, so it has to be
   legible. Unstyled anchors take the browser's default blue, which on these
   dark panels is very close to invisible — the same fault the navigation had. */
.empty-state a {
    color: var(--primary-color);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.empty-state a:hover {
    color: #fff;
}

/* Something went wrong, said in the one colour that means that.
   Scoped to the checkout page before, which is why the listing page rendered
   its failure in ordinary body text and the app had no shared way to say
   "this is a problem". --danger-color is a red now; see _variables.css. */
.error-message {
    color: var(--danger-color);
}

/* An empty state that is reporting a failure rather than an absence.
   `.empty-state p` sets the body colour and outranks a lone `.error-message`,
   so the red has to be claimed here or the message comes out looking like
   ordinary prose. */
.empty-state .error-message {
    color: var(--danger-color);
    margin-bottom: 20px;
    opacity: 1;
}


/* utilities/_instructions.css */
/**
 * Instructions Utilities
 * Styles for instruction sections, setup steps, and informational content
 */

.page-hint {
    color: var(--text-dim);
    font-size: 0.9em;
    margin: 0 0 12px;
}

.form-hint {
    display: block;
    color: var(--text-dim);
    font-size: 0.8em;
    margin-top: 4px;
}

.instructions {
    text-align: left;
    display: inline-block;
    color: var(--text-light);
    line-height: 2;
}

.instructions-section {
    background: rgba(0, 0, 0, 0.3);
    padding: 20px;
    border-radius: 8px;
    border: 1px solid var(--border-color);
    margin-bottom: 30px;
}

.instructions-section h3 {
    color: var(--primary-color);
    margin-bottom: 15px;
}

.setup-steps {
    margin-left: 20px;
    color: var(--text-light);
}

.setup-steps li {
    margin-bottom: 15px;
    line-height: 1.6;
}

.setup-steps li strong {
    color: var(--primary-color);
}

.setup-steps ul {
    margin-top: 8px;
    margin-left: 20px;
    list-style-type: disc;
}

.setup-steps code {
    background: rgba(0, 0, 0, 0.4);
    padding: 3px 8px;
    border-radius: 4px;
    color: var(--primary-color);
    font-family: 'Courier New', monospace;
    font-size: 0.9em;
}

.info-text {
    color: var(--text-light);
    margin-bottom: 12px;
    line-height: 1.6;
}

.feature-list {
    list-style: none;
    margin: 15px 0;
    padding-left: 0;
}

.feature-list li {
    color: var(--text-light);
    padding: 8px 0;
    line-height: 1.6;
}

.simple-steps {
    margin-left: 20px;
    color: var(--text-light);
    margin-top: 10px;
}

.simple-steps li {
    padding: 6px 0;
    line-height: 1.6;
}


/* pages/_base-pages.css */
/**
 * Base Page Styles
 * Shared styles for standard campaign pages
 */

/* Base styles for ALL campaign pages (with or without sidebar) */
.home-page,
.items-page,
.factions-page,
.shops-page,
.notes-page,
.story-page,
.pantheon-page,
.classes-page,
.races-page,
.features-page,
.backgrounds-page,
.geography-page,
.maps-page,
.store-page,
.store-creator-page,
.store-purchases-page,
.store-listing-page,
.store-checkout-page {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    padding: 40px 40px 0 20px; /* Top, Right, Bottom, Left - base padding for all pages */
    background: linear-gradient(135deg, var(--abyssal-dark) 0%, var(--abyssal-purple) 100%);
    background-attachment: fixed;
    color: var(--abyssal-light);
    margin: 0;
    min-height: 100vh;
    transition: padding-left 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

/* ADDITIONAL left padding when sidebar is present (collapsed state) */
body:has(.sidebar-nav) .home-page,
body:has(.sidebar-nav) .items-page,
body:has(.sidebar-nav) .factions-page,
body:has(.sidebar-nav) .shops-page,
body:has(.sidebar-nav) .notes-page,
body:has(.sidebar-nav) .story-page,
body:has(.sidebar-nav) .pantheon-page,
body:has(.sidebar-nav) .classes-page,
body:has(.sidebar-nav) .races-page,
body:has(.sidebar-nav) .features-page,
body:has(.sidebar-nav) .backgrounds-page,
body:has(.sidebar-nav) .geography-page,
body:has(.sidebar-nav) .maps-page,
body:has(.sidebar-nav) .store-page,
body:has(.sidebar-nav) .store-creator-page,
body:has(.sidebar-nav) .store-purchases-page,
body:has(.sidebar-nav) .store-listing-page,
body:has(.sidebar-nav) .store-checkout-page {
    padding-left: calc(56px + 20px); /* Sidebar width (collapsed) + base padding */
}


/* Form list pages share the same structure */
/* See pages/_form-list-pages.css for shared styles applied to: */
/* factions-page, shops-page, classes-page, races-page, features-page, backgrounds-page */

/* Notes page - override with different padding values */
.notes-page {
    padding: 30px; /* Override all padding for notes */
}

/* Notes page - ADDITIONAL left padding when sidebar is present (collapsed) */
body:has(.sidebar-nav) .notes-page {
    padding-left: calc(56px + 30px); /* Sidebar width (collapsed) + notes padding */
}


/* Story page - additional flex properties */
.story-page {
    display: flex;
    justify-content: center;
    align-items: flex-start;
    padding: 32px 24px 48px; /* Override with story-specific padding */
}

/* Story page - ADDITIONAL left padding when sidebar is present (collapsed) */
body:has(.sidebar-nav) .story-page {
    padding-left: calc(56px + 24px); /* Sidebar width (collapsed) + story padding */
}


/* Utility classes */
.page-title-icon {
    vertical-align: middle;
    margin-right: 10px;
    filter: drop-shadow(0 0 10px color-mix(in srgb, var(--primary-color) 40%, transparent));
}

.is-hidden {
    display: none !important;
}

.text-muted {
    color: var(--text-dim);
    opacity: 0.8;
}

/* pages/_splash.css */
/**
 * Splash/Welcome Page Styles
 */

/* Splash Screen Container - Full Screen Overlay */
#splash-screen {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    z-index: 9999;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: rgba(0, 0, 0, 0.9);
    backdrop-filter: blur(4px);
    padding: 0;
    margin: 0;
    box-sizing: border-box;
    will-change: opacity;
}

#splash-screen.hidden {
    display: none !important;
}

/* Splash Content Container - Centered Card */
.splash-content {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: auto;
    max-width: 90vw;
    max-height: 90vh;
    padding: 40px;
    box-sizing: border-box;
    gap: 30px;
    margin: auto;
}

/* Splash Frame (iframe) */
#splash-frame {
    width: 800px;
    max-width: 90vw;
    height: 600px;
    max-height: 70vh;
    border: none;
    background: transparent;
    border-radius: 16px;
    overflow: hidden;
}

/* Splash OK Button */
#splash-ok-btn,
.splash-ok-btn {
    padding: 14px 32px;
    font-size: 1.1em;
    font-weight: 600;
    color: var(--text-light);
    background: linear-gradient(135deg, var(--primary-color), var(--accent-color));
    border: 2px solid var(--primary-color);
    border-radius: 8px;
    cursor: pointer;
    transition: all 0.3s ease;
    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
    text-transform: uppercase;
    letter-spacing: 1px;
    z-index: 10;
    backdrop-filter: blur(10px);
    flex-shrink: 0;
    min-height: 48px;
}

#splash-ok-btn:hover,
.splash-ok-btn:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 20px color-mix(in srgb, var(--primary-color) 50%, transparent);
    border-color: var(--accent-color);
    background: linear-gradient(135deg, var(--accent-color), var(--primary-color));
}

#splash-ok-btn:active,
.splash-ok-btn:active {
    transform: translateY(0);
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
}

/* Splash Page Content (inside iframe) */
.splash-page {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background: linear-gradient(
        135deg,
        var(--theme-color-2, var(--abyssal-dark)) 0%,
        color-mix(in srgb, var(--theme-color-2, var(--abyssal-dark)) 80%, color-mix(in srgb, var(--theme-color-4, var(--accent-color)) 60%, var(--theme-color-5, var(--secondary-color)) 40%) 20%) 45%,
        var(--theme-color-2, var(--abyssal-dark)) 100%
    );
    color: var(--text-light);
    margin: 0;
    padding: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 100vh;
}

.splash-page .version-display {
    text-align: center;
}

.splash-page .logo-header {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 30px;
    margin-bottom: 40px;
    animation: fadeInScale 0.8s ease-out;
    will-change: transform, opacity;
}

.splash-page .logo-header img {
    height: 400px;
    width: auto;
    border-radius: 20px;
    filter: drop-shadow(0 0 20px color-mix(in srgb, var(--primary-color) 60%, transparent));
    animation: logoFloat 4s ease-in-out infinite, logoGlow 3s ease-in-out infinite;
    transform-origin: center;
    will-change: transform, filter;
}

.splash-page .version-text {
    position: fixed;
    top: 20px;
    right: 20px;
    font-size: 0.9em;
    color: var(--text-light);
    opacity: 0.6;
    font-weight: normal;
    animation: fadeIn 1s ease-out 0.5s both;
    z-index: 10;
}

.splash-page .version-label {
    font-size: 2.5em;
    color: var(--primary-color);
    text-transform: none;
    letter-spacing: normal;
    margin-bottom: 20px;
    text-shadow: 0 0 10px var(--shadow-primary-35);
    animation: fadeInUp 0.8s ease-out 0.3s both;
    will-change: transform, opacity;
}

.splash-page #campaign-info {
    margin-top: 30px;
    display: none;
    animation: fadeInUp 0.6s ease-out 0.5s both;
    will-change: transform, opacity;
}

.splash-page #campaign-info.show {
    display: block;
}

.splash-page #campaign-setting {
    font-size: 1.2em;
    color: var(--text-light);
    font-style: italic;
    animation: fadeInUp 0.6s ease-out 0.6s both;
    will-change: transform, opacity;
}

@media (max-width: 768px) {
    .splash-content {
        padding: 20px 15px;
        gap: 20px;
        max-width: 95vw;
        max-height: 95vh;
    }

    #splash-frame {
        width: 100%;
        max-width: 95vw;
        height: 400px;
        max-height: 60vh;
    }

    #splash-ok-btn,
    .splash-ok-btn {
        padding: 12px 24px;
        font-size: 1em;
        width: 100%;
        max-width: 300px;
    }

    .splash-page .logo-header {
        flex-direction: column;
        gap: 20px;
    }

    .splash-page .logo-header img {
        height: 250px;
    }

    .splash-page .version-text {
        font-size: 0.8em;
    }
}


/* pages/_auth.css */
/**
 * Authentication Pages (Login, Register)
 * Clean, typical login screen styling
 */

.auth-page {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background: linear-gradient(135deg, var(--theme-color-2, var(--abyssal-dark)) 0%, var(--theme-color-1, var(--abyssal-purple)) 100%);
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    margin: 0;
}

.auth-container {
    width: 100%;
    max-width: 420px;
    margin: 0 auto;
}

.auth-card {
    background: color-mix(in srgb, var(--surface-panel, rgba(45, 45, 58, 0.95)) 98%, white 2%);
    border-radius: 12px;
    box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3);
    border: 1px solid var(--border-color, rgba(255, 255, 255, 0.1));
    padding: 40px;
    width: 100%;
    box-sizing: border-box;
    backdrop-filter: blur(10px);
}

.auth-header {
    text-align: center;
    margin-bottom: 30px;
}

.auth-logo {
    width: 80px;
    height: auto;
    margin: 0 auto 20px;
    display: block;
    border-radius: 8px;
}

.auth-header h1 {
    font-size: 28px;
    font-weight: 600;
    color: var(--text-light, #ffffff);
    margin: 0 0 8px 0;
}

.auth-subtitle {
    color: var(--text-secondary, rgba(255, 255, 255, 0.7));
    font-size: 14px;
    margin: 0;
}

.auth-form {
    width: 100%;
}

.auth-form .form-group {
    margin-bottom: 20px;
}

.auth-form .form-group label {
    display: block;
    font-size: 14px;
    font-weight: 500;
    color: var(--text-light, #ffffff);
    margin-bottom: 8px;
}

.auth-form .form-group input {
    width: 100%;
    padding: 12px 16px;
    font-size: 15px;
    border: 2px solid var(--border-color, rgba(255, 255, 255, 0.2));
    border-radius: 8px;
    background: color-mix(in srgb, var(--surface-panel, rgba(45, 45, 58, 0.8)) 90%, transparent 10%);
    color: var(--text-light, #ffffff);
    box-sizing: border-box;
    transition: border-color 0.2s ease, background 0.2s ease;
}

.auth-form .form-group input:focus {
    outline: none;
    border-color: var(--primary-color, var(--abyssal-glow));
    background: color-mix(in srgb, var(--surface-panel, rgba(45, 45, 58, 0.95)) 95%, transparent 5%);
}

.auth-form .form-group input::placeholder {
    color: var(--text-dim, rgba(255, 255, 255, 0.5));
}

/* A checkbox and its words on one line (the 18+ confirmation, S-1 FR-10). */
.auth-form .form-group.form-check label {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 0;
    cursor: pointer;
}

.auth-form .form-group.form-check input[type="checkbox"] {
    width: 18px;
    height: 18px;
    padding: 0;
    flex: none;
    accent-color: var(--primary-color, var(--abyssal-glow));
}

.auth-form .btn-primary {
    width: 100%;
    padding: 14px;
    font-size: 16px;
    font-weight: 600;
    background: linear-gradient(135deg, var(--primary-color, var(--abyssal-glow)) 0%, var(--accent-color, var(--abyssal-accent)) 100%);
    color: var(--text-light, #ffffff);
    border: 1px solid var(--primary-color, var(--abyssal-glow));
    border-radius: 8px;
    cursor: pointer;
    transition: transform 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
    margin-top: 10px;
}

.auth-form .btn-primary:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 12px color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 40%, transparent);
    border-color: var(--accent-color, var(--abyssal-accent));
}

.auth-form .btn-primary:active {
    transform: translateY(0);
}

.auth-form .btn-primary:disabled {
    opacity: 0.6;
    cursor: not-allowed;
    transform: none;
}

.error-message {
    background: color-mix(in srgb, var(--danger-color, #EC4899) 15%, transparent);
    color: var(--danger-color, #EC4899);
    padding: 12px;
    border-radius: 6px;
    font-size: 14px;
    margin-bottom: 20px;
    border: 1px solid color-mix(in srgb, var(--danger-color, #EC4899) 40%, transparent);
}

.auth-footer {
    margin-top: 24px;
    text-align: center;
    padding-top: 20px;
    border-top: 1px solid var(--border-color, rgba(255, 255, 255, 0.1));
}

.auth-footer p {
    margin: 0;
    font-size: 13px;
    color: var(--text-secondary, rgba(255, 255, 255, 0.7));
}

/* Links on the auth pages had no colour of their own, so they fell back to the
 * browser default — #0000EE, pure blue, on a dark navy card. "Forgot your
 * password?" and "Create one" were nearly unreadable, which is unfortunate for
 * the two links a stuck user most needs to find. */
.auth-page a {
    color: var(--primary-color, #4DD0E1);
    text-decoration: none;
    font-weight: 600;
    transition: color 0.15s ease;
}

.auth-page a:hover,
.auth-page a:focus-visible {
    color: var(--accent-color, #1FC89B);
    text-decoration: underline;
}

.auth-page a:focus-visible {
    outline: 2px solid var(--accent-color, #1FC89B);
    outline-offset: 3px;
    border-radius: 2px;
}

/* Responsive */
@media (max-width: 480px) {
    .auth-card {
        padding: 30px 24px;
    }
    
    .auth-header h1 {
        font-size: 24px;
    }
    
    .auth-logo {
        width: 60px;
    }
}


/* pages/_home.css */
/**
 * Home Page Styles
 */

.home-page {
    /* A campaign command centre, not a document — it wants the room. */
    --page-max: 1600px;
}

.home-page .container {
    padding: 20px 40px; /* Horizontal padding for readability - IDE style */
    padding-top: 60px;
    margin: 0 auto; /* Center content */
    max-width: var(--page-max);
    width: 100%;
    box-sizing: border-box;
}

.home-page h2 {
    color: var(--secondary-color);
    margin-bottom: 15px;
    font-size: 1.8em;
    font-weight: 600;
}

.home-page p {
    line-height: 1.6;
    color: var(--text-light);
    opacity: 0.9;
}

/* The campaign's name and premise, as a masthead rather than a card. It was a
   30px-padded panel with its own shadow and stripe, taking a third of the first
   screen to say what the page is already about. */
.home-page .welcome-card {
    padding: 0 0 14px;
    margin-bottom: 18px;
    border: none;
    border-bottom: 1px solid color-mix(in srgb, var(--primary-color) 30%, transparent);
    background: none;
    box-shadow: none;
    backdrop-filter: none;
}

.home-page .welcome-content h2 {
    color: var(--primary-color);
    font-size: 1.6em;
    margin-bottom: 6px;
}

.home-page .welcome-content p {
    font-size: 0.92em;
    line-height: 1.6;
    margin-bottom: 0;
    /* The premise is scene-setting, not something to re-read every visit. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    opacity: 0.85;
}

.home-page .welcome-content .hint-text {
    font-size: 0.95em;
    opacity: 0.7;
    font-style: italic;
    color: var(--text-dim);
}

/* A command centre rather than a stack of cards.
   Each section was a 30px-padded panel with a 4px accent stripe, a shadow, and
   a lift on hover — and inside it a second panel, .section-header, 62px tall
   with its own background, holding one short heading. That header alone was a
   fifth to a quarter of every section's height, and five sections of it made
   the page a column of boxes you scrolled past to reach anything. Content that
   jumps when the mouse crosses it did not help. */
.home-page .section {
    margin: 18px 0;
    padding: 18px 20px;
    background: var(--panel-75);
    border-radius: 10px;
    border-left: 3px solid var(--primary-color);
    backdrop-filter: blur(10px);
}

/* The heading is a heading, not a panel. */
.home-page .section-header {
    background: none;
    padding: 0;
    margin-bottom: 12px;
    border: none;
    min-height: 0;
}

.home-page .section-header h2,
.home-page .section h2 {
    margin: 0;
    font-size: 1.05rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--secondary-color);
}

.home-page .section-description {
    margin: 0 0 12px;
    font-size: 0.86rem;
    opacity: 0.75;
}

/* The status board sits full width at the top; everything else pairs off
   beneath it, so the page is two screens of content rather than five. */
/* `hidden` has to win. .overview-card sets display:flex, and an explicit
   display beats the browser's own [hidden] { display: none } — so the "Needs
   you" card sat there empty with nothing in it, which is exactly the furniture
   it was written to avoid becoming. */
.home-page .overview-card[hidden] {
    display: none;
}

/* The card that only appears when something is waiting. It has to read as
   different from the four that are always there, or it is just a fifth card. */
.home-page .overview-card.is-waiting {
    border-color: var(--accent-color);
    background: color-mix(in srgb, var(--accent-color) 10%, var(--panel-60));
}

.home-page .overview-card.is-waiting .overview-card-title {
    color: var(--accent-color);
    opacity: 1;
}

/* The last few things said and rolled, under the "when". */
.home-page .overview-recent li {
    display: block;
}

.home-page .overview-recent .overview-list-name {
    display: block;
    font-size: 0.8rem;
    opacity: 0.8;
    white-space: normal;
    overflow: visible;
}

/* Character names in the party card are links to their sheets. */
.home-page a.overview-list-name {
    color: inherit;
    text-decoration: none;
    border-bottom: 1px solid transparent;
}

.home-page a.overview-list-name:hover {
    color: var(--abyssal-glow);
    border-bottom-color: var(--abyssal-glow);
}

/* Setting the chapter is the point of the card, so the control is the card. */
.home-page .chapter-select {
    width: 100%;
    padding: 7px 9px;
    margin-bottom: 8px;
    background: var(--panel-75);
    border: 1px solid var(--abyssal-glow);
    border-radius: 6px;
    color: var(--text-light);
    font-family: inherit;
    font-size: 0.88rem;
}

.home-page .chapter-select:focus {
    outline: none;
    border-color: var(--accent-color);
}

/* What the campaign is set to, at a glance. */
.home-page .settings-summary {
    display: flex;
    flex-direction: column;
    gap: 6px;
    margin: 4px 0 14px;
}

.home-page .settings-summary-row {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 7px 10px;
    background: var(--panel-60);
    border-radius: 6px;
    font-size: 0.86rem;
}

.home-page .settings-summary-label {
    opacity: 0.75;
}

.home-page .settings-summary-value {
    font-weight: 600;
    color: var(--abyssal-glow);
}

.home-page .settings-open {
    margin-bottom: 18px;
}

/* Equal halves. The setting and the journal are the two things you write in —
   what the world is, and what happened in it — so neither gets more room. */
.home-page .command-columns {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 18px;
    align-items: stretch;
}

.home-page .command-col {
    display: flex;
    flex-direction: column;
}

/* Both sections fill their column, so the two stay the same height whichever
   has more in it. */
.home-page .command-col > .section {
    margin: 0;
    flex: 1;
    display: flex;
    flex-direction: column;
}

/* The setting box grows with its column too, rather than leaving the gap the
   journal's height creates beside it. Both sides fill; neither is padding. */
.home-page .command-col .editable-field {
    display: flex;
    flex-direction: column;
    flex: 1;
}

.home-page .command-col .editable-field textarea {
    flex: 1;
}

@media (max-width: 900px) {
    .home-page .command-columns {
        grid-template-columns: 1fr;
    }
}


/* pages/_form-list-pages.css */
/**
 * Form List Pages - Shared Styles
 * Used by: factions-page, shops-page, classes-page, races-page, features-page, backgrounds-page, geography-page
 * 
 * These pages all share the same structure:
 * - List of items in a grid (geography has unique list layout but same cards)
 * - Item cards with name, type badge, details
 * - Modal forms for editing
 * - Image previews
 * 
 * NOTE: Character-detail and NPC-detail pages also use these card styles when displaying items.
 * All editing forms across all pages should use these shared form styles.
 */

/* Shared Item Card Styles (used by all form-list pages AND geography page) */
.factions-page .item-card,
.shops-page .item-card,
.classes-page .item-card,
.races-page .item-card,
.features-page .item-card,
.backgrounds-page .item-card,
.geography-page .item-card {
    background: var(--panel-75);
    backdrop-filter: blur(10px);
    border-radius: 6px;
    border-left: 2px solid var(--secondary-color);
    padding: 8px;
    transition: all 0.3s ease;
    position: relative;
    overflow: visible;
    cursor: pointer;
    width: 100%; /* Full width cards */
}

.factions-page .item-card:hover,
.shops-page .item-card:hover,
.classes-page .item-card:hover,
.races-page .item-card:hover,
.features-page .item-card:hover,
.backgrounds-page .item-card:hover,
.geography-page .item-card:hover {
    transform: translateY(-3px);
    box-shadow: 0 4px 20px var(--shadow-primary-35);
}

.factions-page .item-name,
.shops-page .item-name,
.classes-page .item-name,
.races-page .item-name,
.features-page .item-name,
.backgrounds-page .item-name,
.geography-page .item-name {
    color: var(--primary-color);
    font-size: 0.9em;
    font-weight: 600;
    margin-bottom: 8px;
    word-wrap: break-word;
    overflow-wrap: break-word;
}

.factions-page .item-type-badge,
.shops-page .item-type-badge,
.classes-page .item-type-badge,
.races-page .item-type-badge,
.features-page .item-type-badge,
.backgrounds-page .item-type-badge {
    padding: 4px 10px;
    border-radius: 12px;
    font-size: 0.75em;
    font-weight: 600;
    background: var(--accent-secondary-20);
    color: var(--secondary-color);
    text-transform: uppercase;
}

.factions-page .item-details,
.shops-page .item-details,
.classes-page .item-details,
.races-page .item-details,
.features-page .item-details,
.backgrounds-page .item-details,
.geography-page .item-details {
    font-size: 0.9em;
    color: var(--text-light);
    margin-top: 8px;
}

.factions-page .item-details .item-meta-line,
.shops-page .item-details .item-meta-line,
.classes-page .item-details .item-meta-line,
.races-page .item-details .item-meta-line,
.features-page .item-details .item-meta-line,
.backgrounds-page .item-details .item-meta-line {
    margin-bottom: 4px;
    word-wrap: break-word;
    overflow-wrap: break-word;
}

.factions-page .item-description,
.shops-page .item-description,
.classes-page .item-description,
.races-page .item-description,
.features-page .item-description,
.backgrounds-page .item-description {
    margin-top: 8px;
    opacity: 0.8;
    line-height: 1.4;
    word-wrap: break-word;
    overflow-wrap: break-word;
}

.factions-page .item-image,
.shops-page .item-image,
.classes-page .item-image,
.races-page .item-image,
.features-page .item-image,
.backgrounds-page .item-image {
    width: 50px;
    height: 50px;
    border-radius: 8px;
    object-fit: cover;
    border: 2px solid var(--secondary-color);
}

/* Shared Form Styles - Used by all form-list pages AND geography page */
.factions-page .form-group,
.shops-page .form-group,
.classes-page .form-group,
.races-page .form-group,
.features-page .form-group,
.backgrounds-page .form-group,
.geography-page .form-group {
    margin-bottom: 20px;
}

.form-list-page .form-group label {
    display: block;
    color: var(--primary-color);
    margin-bottom: 8px;
    font-weight: 600;
}

.factions-page .form-group input,
.factions-page .form-group select,
.factions-page .form-group textarea,
.shops-page .form-group input,
.shops-page .form-group select,
.shops-page .form-group textarea,
.classes-page .form-group input,
.classes-page .form-group select,
.classes-page .form-group textarea,
.races-page .form-group input,
.races-page .form-group select,
.races-page .form-group textarea,
.features-page .form-group input,
.features-page .form-group select,
.features-page .form-group textarea,
.backgrounds-page .form-group input,
.backgrounds-page .form-group select,
.backgrounds-page .form-group textarea,
.geography-page .form-group input,
.geography-page .form-group select,
.geography-page .form-group textarea {
    width: 100%;
    padding: 10px;
    background: var(--panel-60);
    border: 2px solid var(--secondary-color);
    border-radius: 6px;
    color: var(--text-light);
    font-size: 1em;
    font-family: inherit;
}

.factions-page .form-group textarea,
.shops-page .form-group textarea,
.classes-page .form-group textarea,
.races-page .form-group textarea,
.features-page .form-group textarea,
.backgrounds-page .form-group textarea,
.geography-page .form-group textarea {
    min-height: 120px;
    resize: vertical;
}

.factions-page .form-group input:focus,
.factions-page .form-group select:focus,
.factions-page .form-group textarea:focus,
.shops-page .form-group input:focus,
.shops-page .form-group select:focus,
.shops-page .form-group textarea:focus,
.classes-page .form-group input:focus,
.classes-page .form-group select:focus,
.classes-page .form-group textarea:focus,
.races-page .form-group input:focus,
.races-page .form-group select:focus,
.races-page .form-group textarea:focus,
.features-page .form-group input:focus,
.features-page .form-group select:focus,
.features-page .form-group textarea:focus,
.backgrounds-page .form-group input:focus,
.backgrounds-page .form-group select:focus,
.backgrounds-page .form-group textarea:focus,
.geography-page .form-group input:focus,
.geography-page .form-group select:focus,
.geography-page .form-group textarea:focus {
    outline: none;
    border-color: var(--secondary-color);
    box-shadow: 0 0 10px var(--shadow-primary-35);
}

.factions-page .form-group small,
.shops-page .form-group small,
.classes-page .form-group small,
.races-page .form-group small,
.features-page .form-group small,
.backgrounds-page .form-group small,
.geography-page .form-group small {
    color: var(--text-light, var(--abyssal-light));
    opacity: 0.7;
    display: block;
    margin-top: 4px;
}

/* Shared Image Preview */
.factions-page .image-preview,
.shops-page .image-preview,
.classes-page .image-preview,
.races-page .image-preview,
.features-page .image-preview,
.backgrounds-page .image-preview,
.geography-page .image-preview {
    margin-top: 10px;
    max-width: 200px;
}

.factions-page .image-preview img,
.shops-page .image-preview img,
.classes-page .image-preview img,
.races-page .image-preview img,
.features-page .image-preview img,
.backgrounds-page .image-preview img,
.geography-page .image-preview img {
    width: 100%;
    height: auto;
    border-radius: 8px;
    border: 2px solid var(--secondary-color);
}

/* Shared Modal Styles - Used by all form-list pages */
.factions-page .modal,
.shops-page .modal,
.classes-page .modal,
.races-page .modal,
.features-page .modal,
.backgrounds-page .modal,
.geography-page .modal {
    display: none;
    position: fixed;
    z-index: 1000;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.8);
    backdrop-filter: blur(5px);
}

.factions-page .modal.show,
.shops-page .modal.show,
.classes-page .modal.show,
.races-page .modal.show,
.features-page .modal.show,
.backgrounds-page .modal.show,
.geography-page .modal.show {
    display: flex;
    align-items: center;
    justify-content: center;
}

.factions-page .modal-content,
.shops-page .modal-content,
.classes-page .modal-content,
.races-page .modal-content,
.features-page .modal-content,
.backgrounds-page .modal-content,
.geography-page .modal-content {
    background: var(--panel-75);
    border: 2px solid var(--secondary-color);
    border-radius: 12px;
    padding: 30px;
    max-width: 800px;
    width: 90%;
    max-height: 80vh;
    overflow-y: auto;
    position: relative;
}

/* All styles above target these pages directly */
/* Page-specific overrides below */

/* Shops page specific - narrower modal */
.shops-page .modal-content {
    max-width: 700px;
}

/* Factions page specific - parent faction display */
.factions-page .parent-faction {
    font-size: 0.85em;
    color: var(--text-dim);
    margin-top: 4px;
    font-style: italic;
}


/* components/_dice-selector.css */
/**
 * The dice selector: pick a die, a quantity, a modifier.
 *
 * Not scoped to a page. It was — every rule began `.items-page`, which items
 * and spells both carry and nothing else does, so the first page to reuse the
 * widget rendered raw unsized images the height of the panel.
 */
.dice-selector {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    margin-bottom: 10px;
    padding: 10px;
    background: var(--panel-40);
    border-radius: 6px;
}

.dice-btn {
    min-width: 50px;
    height: 45px;
    padding: 0 12px;
    border: 2px solid var(--primary-color);
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--accent-primary-20);
    color: var(--primary-color);
    font-size: 16px;
    font-weight: bold;
    cursor: pointer;
    transition: all 0.2s ease;
    gap: 6px;
}

.dice-btn:hover {
    background: var(--accent-primary-35);
    transform: scale(1.05);
    box-shadow: 0 0 10px var(--shadow-primary-35);
}

.dice-btn.active {
    background: var(--primary-color);
    color: var(--bg-dark);
    box-shadow: 0 0 15px var(--shadow-primary-50);
}

.dice-icon {
    width: 24px;
    height: 24px;
}

.dice-selector-controls {
    display: flex;
    gap: 8px;
    align-items: center;
    margin-top: 8px;
    flex-wrap: wrap;
}

.dice-quantity {
    display: flex;
    align-items: center;
    gap: 6px;
}

.dice-quantity-label {
    font-size: 0.85em;
    color: color-mix(in srgb, var(--text-light) 80%, transparent);
}

.dice-quantity input {
    width: 60px;
    padding: 6px;
    background: var(--panel-60);
    border: 2px solid color-mix(in srgb, var(--item-consumable-color) 30%, transparent);
    border-radius: 4px;
    color: var(--text-light);
    text-align: center;
}

.dice-value {
    color: var(--abyssal-glow);
    font-weight: 600;
}

/* Clears an optional selector back to no dice at all. */
.dice-clear {
    padding: 4px 12px;
    border: 1px solid color-mix(in srgb, var(--text-light) 35%, transparent);
    border-radius: 4px;
    background: transparent;
    color: var(--text-light);
    font-size: 0.85em;
    cursor: pointer;
}

.dice-clear:hover {
    border-color: var(--primary-color);
    color: var(--primary-color);
}


/* pages/_items-page.css */
/**
 * Items Page - Unique Styles
 * Items page has unique features like dice selectors and item type colors
 * that other form-list pages don't need
 */

.items-page {
    --item-weapon-color: var(--abyssal-teal);
    --item-armor-color: var(--accent-color);
    --item-consumable-color: var(--secondary-color);
}

/* Items page uses shared .item-card from components/_cards.css */
/* But has unique item-card variants for different item types */
.items-page .item-card.spell {
    border-left-color: var(--abyssal-glow);
}

.items-page .item-card.weapon {
    border-left-color: var(--item-weapon-color);
}

.items-page .item-card.armor {
    border-left-color: var(--item-armor-color);
}

.items-page .item-card.consumable {
    border-left-color: var(--item-consumable-color);
}

/* Items page type filter */
.items-page #type-filter-container {
    padding: 10px 15px;
    background: var(--panel-60);
    border: 2px solid color-mix(in srgb, var(--item-weapon-color) 40%, transparent);
    border-radius: 8px;
    transition: opacity 0.2s ease;
}

.items-page #type-filter-container.is-locked {
    opacity: 0.8;
    cursor: not-allowed;
}

.items-page #type-filter {
    padding: 8px 12px;
    background: var(--panel-40);
    border: 2px solid var(--primary-color);
    border-radius: 6px;
    color: var(--text-light);
    font-size: 14px;
    cursor: pointer;
    transition: border-color 0.2s ease, box-shadow 0.2s ease, opacity 0.2s ease;
}

.items-page #type-filter:focus {
    outline: none;
    border-color: var(--primary-color);
    box-shadow: 0 0 10px var(--shadow-primary-35);
}

.items-page #type-filter.is-locked {
    opacity: 0.6;
    cursor: not-allowed;
}

/* Items page image handling */
.items-page #item-image {
    width: 100%;
    padding: 8px;
    background: var(--panel-60);
    border: 2px solid var(--primary-color);
    border-radius: 6px;
    color: var(--text-light);
    font-size: 14px;
    cursor: pointer;
}

.items-page #item-remove-image {
    margin-top: 8px;
    padding: 6px 12px;
    background: var(--danger-bg-20);
    border: 1px solid var(--danger-color);
    border-radius: 4px;
    color: var(--danger-color);
    cursor: pointer;
    font-size: 0.85em;
    transition: all 0.2s ease;
}

.items-page #item-remove-image:hover {
    background: var(--danger-bg-35);
}

.items-page #item-image-preview {
    margin-top: 10px;
}

.items-page #item-image-preview .image-placeholder,
.items-page .image-preview-empty {
    width: 100px;
    height: 100px;
    background: var(--panel-40);
    border: 2px dashed var(--primary-color);
    border-radius: 8px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-dim);
    font-size: 0.85em;
}

.items-page .item-image {
    width: 50px;
    height: 50px;
    border-radius: 8px;
    object-fit: cover;
    border: 2px solid var(--primary-color);
}


/* pages/_story.css */
/**
 * Story Page Styles
 * Unique layout with story index panel and detail panel
 */

.story-page {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background: linear-gradient(135deg, var(--abyssal-dark) 0%, var(--abyssal-purple) 100%);
    background-attachment: fixed;
    color: var(--text-light);
    margin: 0;
    min-height: 100vh;
    display: flex;
    justify-content: center;
    align-items: flex-start;
    padding: 32px 24px 48px;
    box-sizing: border-box;
}

.story-page .story-shell {
    width: min(1500px, 100%);
    display: grid;
    grid-template-columns: 360px minmax(0, 1fr);
    gap: 20px;
}

.story-page .story-index-panel {
    background: var(--panel-75);
    border: 1px solid color-mix(in srgb, var(--primary-color) 18%, transparent);
    border-radius: 14px;
    backdrop-filter: blur(18px);
    display: flex;
    flex-direction: column;
    box-shadow: 0 18px 38px var(--shadow-ambient-40);
    overflow: hidden;
}

.story-page .panel-header {
    padding: 18px 20px;
    border-bottom: 1px solid color-mix(in srgb, var(--primary-color) 12%, transparent);
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.story-page .panel-header h1 {
    margin: 0;
    font-size: 1.9rem;
    color: var(--primary-color);
    display: flex;
    align-items: center;
    gap: 12px;
}

.story-page .panel-header h1 svg {
    width: 28px;
    height: 28px;
}

.story-page .story-actions {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}

.story-page .story-action-buttons {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

.story-page .story-search-group {
    display: flex;
    gap: 10px;
    align-items: center;
    flex: 1;
}

.story-page .story-search-group input {
    flex: 1;
    padding: 10px 12px;
    border-radius: 8px;
    border: 1px solid color-mix(in srgb, var(--primary-color) 25%, transparent);
    background: var(--panel-60);
    color: var(--text-light);
    font-size: 0.95rem;
}

.story-page .story-search-group input:focus {
    outline: none;
    border-color: var(--primary-color);
    box-shadow: 0 0 12px var(--shadow-primary-35);
}

.story-page .story-count {
    font-size: 0.9rem;
    color: var(--text-light);
    opacity: 0.75;
}

.story-page .story-list {
    flex: 1;
    overflow-y: auto;
    padding: 8px 0;
    scrollbar-width: thin;
}

.story-page .story-list::-webkit-scrollbar {
    width: 6px;
}

.story-page .story-list::-webkit-scrollbar-thumb {
    background: var(--accent-primary-35);
    border-radius: 4px;
}

.story-page .story-row {
    display: grid;
    grid-template-columns: auto minmax(0, 1fr) auto;
    align-items: center;
    gap: 10px;
    padding: 12px 18px;
    cursor: pointer;
    border-left: 3px solid transparent;
    transition: background 0.2s ease, border-color 0.2s ease, transform 0.1s ease;
}

.story-page .story-row:hover {
    background: var(--accent-primary-20);
}

.story-page .story-row.active {
    border-left-color: var(--primary-color);
    background: linear-gradient(
        135deg,
        color-mix(in srgb, var(--primary-color) 25%, transparent) 0%,
        color-mix(in srgb, var(--highlight-color) 40%, transparent) 100%
    );
}

.story-page .story-row .chapter-badge {
    min-width: 78px;
    padding: 4px 10px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--highlight-color) 25%, transparent);
    color: var(--primary-color);
    font-size: 0.8rem;
    font-weight: 600;
    text-align: center;
}

.story-page .story-row .title {
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--text-light);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.story-page .story-row .status-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: color-mix(in srgb, var(--primary-color) 50%, transparent);
}

.story-page .story-row[data-status="in-progress"] .status-dot {
    background: color-mix(in srgb, var(--danger-color) 75%, transparent);
}

.story-page .story-row[data-status="completed"] .status-dot {
    background: color-mix(in srgb, var(--success-color) 75%, transparent);
}

.story-page .story-detail-panel {
    background: var(--panel-75);
    border: 1px solid color-mix(in srgb, var(--primary-color) 20%, transparent);
    border-radius: 16px;
    backdrop-filter: blur(22px);
    padding: 28px;
    box-shadow: 0 22px 44px var(--shadow-ambient-55);
    display: flex;
    flex-direction: column;
    gap: 24px;
}

.story-page .detail-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
}

.story-page .detail-title {
    display: flex;
    align-items: center;
    gap: 16px;
    flex-wrap: wrap;
}

.story-page .detail-title h2 {
    margin: 0;
    font-size: 1.8rem;
    color: var(--primary-color);
}

.story-page .detail-chapter {
    padding: 5px 14px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--highlight-color) 28%, transparent);
    font-weight: 600;
    color: var(--accent-color);
}

.story-page .detail-status {
    padding: 6px 12px;
    border-radius: 999px;
    font-size: 0.85rem;
    font-weight: 600;
    text-transform: capitalize;
    background: var(--accent-primary-20);
    color: var(--text-light);
}

.story-page .detail-status.completed {
    background: var(--accent-secondary-20);
    color: var(--secondary-color);
}

.story-page .detail-status.in-progress {
    background: var(--danger-bg-20);
    color: var(--danger-color);
}

.story-page .reference-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

.story-page .reference-pill {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 8px 12px;
    background: color-mix(in srgb, var(--surface-panel) 80%, transparent 20%);
    border: 1px solid color-mix(in srgb, var(--primary-color) 25%, transparent);
    border-radius: 999px;
    color: var(--text-light);
    font-size: 0.85rem;
    cursor: pointer;
    transition: border-color 0.2s ease, background 0.2s ease;
}

.story-page .reference-pill:hover {
    border-color: var(--primary-color);
    background: var(--accent-primary-20);
}

.story-page .detail-sections {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.story-page .detail-section {
    background: var(--glass-60);
    border-radius: 12px;
    border: 1px solid color-mix(in srgb, var(--highlight-color) 25%, transparent);
    overflow: hidden;
}

.story-page .detail-section summary {
    padding: 14px 18px;
    cursor: pointer;
    font-weight: 600;
    color: var(--primary-color);
    display: flex;
    align-items: center;
    justify-content: space-between;
}

.story-page .detail-section[open] summary {
    background: color-mix(in srgb, var(--highlight-color) 35%, transparent);
}

.story-page .detail-section-content {
    padding: 18px;
    line-height: 1.7;
    color: var(--text-light);
    white-space: pre-wrap;
}

.story-page .detail-empty {
    text-align: center;
    color: var(--text-light);
    opacity: 0.75;
    line-height: 1.7;
    padding: 40px 20px;
}

.story-page .detail-toolbar {
    display: flex;
    gap: 10px;
    justify-content: flex-end;
}

.story-page .empty-state {
    text-align: center;
    padding: 60px 20px;
    color: var(--text-light);
    opacity: 0.7;
}

.story-page .empty-state h2 {
    color: var(--primary-color);
    margin-bottom: 15px;
}

/* Story Page Modal */
.story-page .modal {
    display: none;
    position: fixed;
    z-index: 1000;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background-color: color-mix(in srgb, var(--shadow-color) 70%, transparent);
    overflow-y: auto;
}

.story-page .modal.show {
    display: flex;
    align-items: center;
    justify-content: center;
}

.story-page .modal-content {
    background: var(--bg-dark);
    padding: 34px;
    border-radius: 16px;
    border: 2px solid var(--primary-color);
    max-width: 620px;
    width: 92%;
    max-height: 92vh;
    overflow-y: auto;
    box-shadow: 0 24px 48px var(--shadow-ambient-55);
}

.story-page .form-group {
    margin-bottom: 20px;
}

.story-page .form-group label {
    display: block;
    color: var(--primary-color);
    font-weight: 600;
    margin-bottom: 8px;
}

.story-page .form-group input,
.story-page .form-group textarea,
.story-page .form-group select {
    width: 100%;
    padding: 10px 12px;
    background: var(--panel-60);
    border: 2px solid color-mix(in srgb, var(--primary-color) 25%, transparent);
    border-radius: 8px;
    color: var(--text-light);
    font-size: 1em;
    font-family: inherit;
}

.story-page .form-group textarea {
    min-height: 110px;
    resize: vertical;
}

.story-page .form-group input:focus,
.story-page .form-group textarea:focus,
.story-page .form-group select:focus {
    outline: none;
    border-color: var(--primary-color);
    box-shadow: 0 0 12px var(--shadow-primary-35);
}

.story-page .image-preview {
    margin-top: 10px;
    max-width: 200px;
}

.story-page .image-preview img {
    width: 100%;
    border-radius: 10px;
    border: 2px solid var(--primary-color);
}

.story-page .modal-actions {
    display: flex;
    gap: 10px;
    justify-content: flex-end;
    margin-top: 24px;
}

.story-page .form-row {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 18px;
}

.story-page .form-section {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.story-page details.advanced-section {
    background: var(--glass-60);
    border: 1px solid color-mix(in srgb, var(--primary-color) 25%, transparent);
    border-radius: 10px;
    padding: 12px 18px 4px;
}

.story-page details.advanced-section[open] {
    background: var(--glass-70);
}

.story-page details.advanced-section summary {
    cursor: pointer;
    font-weight: 600;
    color: var(--primary-color);
    list-style: none;
    display: flex;
    align-items: center;
    gap: 8px;
}

.story-page details.advanced-section summary::marker {
    display: none;
}

.story-page .advanced-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    gap: 16px;
    margin-top: 16px;
}

.story-page .advanced-grid .form-group {
    margin-bottom: 0;
}

.story-page .advanced-textareas {
    display: grid;
    gap: 16px;
    margin-top: 16px;
}


/* pages/_viewer.css */
/**
 * Viewer Page Styles
 * Window management system for campaign viewer
 */

body.viewer-page {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    line-height: 1.6;
    color: var(--text-light, #E0E7FF);
    background: linear-gradient(135deg, var(--abyssal-dark, #031120) 0%, var(--abyssal-purple, #154772) 100%) !important;
    background-attachment: fixed !important;
    min-height: 100vh;
    position: relative;
    overflow: hidden;
    --viewer-panel-95: color-mix(in srgb, var(--surface-base) 95%, transparent 5%);
    --viewer-panel-85: color-mix(in srgb, var(--surface-base) 85%, transparent 15%);
    --viewer-panel-70: color-mix(in srgb, var(--surface-base) 70%, transparent 30%);
    --viewer-overlay: color-mix(in srgb, var(--surface-panel) 40%, transparent 60%);
}

body.viewer-page.has-custom-background {
    background: var(--viewer-background-image, linear-gradient(135deg, var(--abyssal-dark, #031120) 0%, var(--abyssal-purple, #154772) 100%)) !important;
    background-size: cover !important;
    background-position: center !important;
    background-repeat: no-repeat !important;
    background-attachment: fixed !important;
}

.viewer-page .top-banner {
    background: color-mix(in srgb, var(--surface-base) 98%, var(--accent-color) 2%);
    backdrop-filter: blur(10px);
}

.banner-content {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 20px;
    position: relative;
}

.banner-user-info {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-right: 12px;
}

.banner-username {
    color: var(--primary-color);
    font-weight: 500;
    font-size: 0.8em;
    text-transform: capitalize;
}

.banner-user-status {
    color: var(--abyssal-light);
    font-weight: 400;
    font-size: 0.75em;
    opacity: 0.8;
    text-transform: capitalize;
}

.banner-left-actions {
    display: flex;
    align-items: center;
    gap: 6px;
    position: absolute;
    left: 16px;
}

.banner-actions {
    display: flex;
    align-items: center;
    gap: 6px;
    justify-content: flex-end;
    position: absolute;
    right: 16px;
}

/* Window Manager */
.viewer-page .window-manager,
.window-manager {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 10;
    pointer-events: none;
    background: transparent !important;
}

.viewer-page .window {
    position: absolute;
    background: var(--viewer-panel-95, color-mix(in srgb, var(--surface-base, var(--theme-color-2, var(--abyssal-dark, #031120))) 95%, transparent 5%));
    border: 2px solid var(--primary-color, var(--abyssal-glow, #4DD0E1));
    border-radius: 8px;
    box-shadow: 0 8px 32px color-mix(in srgb, var(--primary-color, var(--abyssal-glow, #4DD0E1)) 35%, transparent);
    backdrop-filter: blur(10px);
    pointer-events: all;
    min-width: 300px;
    min-height: 200px;
    display: flex;
    flex-direction: column;
    overflow: visible;
    transition: box-shadow 0.2s ease, border-color 0.2s ease;
    animation: windowAppear 0.3s ease-out;
}

.viewer-page .window-active,
.window-active {
    border-color: var(--accent-color, var(--abyssal-accent, #4DD0E1)) !important;
    box-shadow: 0 12px 48px color-mix(in srgb, var(--primary-color, var(--abyssal-glow, #4DD0E1)) 45%, transparent) !important;
}

.viewer-page .window-header {
    background: linear-gradient(135deg, var(--theme-color-1, var(--abyssal-purple, #154772)), var(--theme-color-3, var(--abyssal-glow, #4DD0E1)));
    color: var(--text-light, var(--abyssal-light, #ffffff));
    padding: 8px 12px;
    cursor: move;
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-weight: bold;
    font-size: 14px;
    user-select: none;
    text-shadow: 0 0 10px color-mix(in srgb, black 50%, transparent);
}

.viewer-page .window-title,
.window-title {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.viewer-page .window-controls,
.window-controls {
    display: flex;
    gap: 4px;
}

.viewer-page .window-control {
    width: 20px;
    height: 20px;
    border: none;
    border-radius: 3px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    font-weight: bold;
    transition: all 0.2s;
}

.viewer-page .window-minimize,
.window-minimize {
    background: color-mix(in srgb, var(--secondary-color, var(--theme-color-2, var(--abyssal-dark, #031120))) 50%, transparent);
    color: var(--surface-base, var(--text-light, var(--abyssal-light, #ffffff)));
}

.viewer-page .window-maximize,
.window-maximize {
    background: color-mix(in srgb, var(--primary-color, var(--abyssal-glow, #4DD0E1)) 50%, transparent);
    color: var(--surface-base, var(--text-light, var(--abyssal-light, #ffffff)));
}

.viewer-page .window-close,
.window-close {
    background: color-mix(in srgb, var(--accent-color, var(--abyssal-accent, #4DD0E1)) 65%, transparent);
    color: var(--text-light, var(--abyssal-light, #ffffff));
}

.viewer-page .window-open-tab,
.window-open-tab {
    background: color-mix(in srgb, var(--primary-color, var(--abyssal-glow, #4DD0E1)) 50%, transparent);
    color: var(--text-light, var(--abyssal-light, #ffffff));
    font-size: 14px;
}

.viewer-page .window-control:hover,
.window-control:hover {
    transform: scale(1.1);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}

.viewer-page .window-content,
.window-content {
    flex: 1;
    padding: 16px;
    overflow-y: auto;
    overflow-x: hidden;
    background: color-mix(in srgb, var(--surface-base, var(--theme-color-2, var(--abyssal-dark, #031120))) 80%, transparent 20%);
    position: relative;
    min-height: 0;
    height: 100%;
    -webkit-overflow-scrolling: touch;
}

.viewer-page .window.maximized .window-content {
    overflow-y: auto;
}

.viewer-page .window-content::-webkit-scrollbar {
    width: 10px;
}

.viewer-page .window-content::-webkit-scrollbar-track {
    background: color-mix(in srgb, var(--surface-base) 50%, transparent 50%);
    border-radius: 5px;
}

.viewer-page .window-content::-webkit-scrollbar-thumb {
    background: color-mix(in srgb, var(--primary-color) 45%, transparent 55%);
    border-radius: 5px;
}

.viewer-page .window-content::-webkit-scrollbar-thumb:hover {
    background: color-mix(in srgb, var(--primary-color) 65%, transparent 35%);
}

.viewer-page .window-content .loaded-content {
    overflow: visible;
    height: auto;
}

.viewer-page .window-content iframe {
    display: block;
    width: 100%;
    height: 100%;
    min-height: 400px;
    border: none;
}

/* Window Resize Handles */
.viewer-page .window-resize-handle {
    position: absolute;
    background: transparent;
}

.viewer-page .window-resize-handle.se {
    bottom: 0;
    right: 0;
    width: 12px;
    height: 12px;
    cursor: se-resize;
}

.viewer-page .window-resize-handle.sw {
    bottom: 0;
    left: 0;
    width: 12px;
    height: 12px;
    cursor: sw-resize;
}

.viewer-page .window-resize-handle.ne {
    top: 0;
    right: 0;
    width: 12px;
    height: 12px;
    cursor: ne-resize;
}

.viewer-page .window-resize-handle.nw {
    top: 0;
    left: 0;
    width: 12px;
    height: 12px;
    cursor: nw-resize;
}

.viewer-page .window-resize-handle.s {
    bottom: 0;
    left: 12px;
    right: 12px;
    height: 12px;
    cursor: s-resize;
}

.viewer-page .window-resize-handle.n {
    top: 0;
    left: 12px;
    right: 12px;
    height: 12px;
    cursor: n-resize;
}

.viewer-page .window-resize-handle.e {
    top: 12px;
    bottom: 12px;
    right: 0;
    width: 12px;
    cursor: e-resize;
}

.viewer-page .window-resize-handle.w {
    top: 12px;
    bottom: 12px;
    left: 0;
    width: 12px;
    cursor: w-resize;
}

body.window-dragging,
body.window-dragging * {
    cursor: move !important;
}

body.window-resizing,
body.window-resizing * {
    cursor: var(--resize-cursor, se-resize) !important;
}

body.window-dragging iframe,
body.window-resizing iframe {
    pointer-events: none !important;
    user-select: none !important;
}

body.window-dragging .window-content,
body.window-resizing .window-content {
    pointer-events: none !important;
    user-select: none !important;
}

.viewer-page .window.minimized {
    height: auto !important;
    min-height: auto;
    animation: windowMinimize 0.2s ease-out;
}

.viewer-page .window.minimized .window-content {
    display: none;
}

.viewer-page .window.restoring {
    animation: windowRestore 0.2s ease-out;
}

.viewer-page .window.maximized {
    top: 40px !important;
    left: 0 !important;
    width: 100vw !important;
    height: calc(100vh - 40px) !important;
    z-index: 1001;
    border-radius: 0;
}

.viewer-page .window.maximized .window-resize-handle {
    display: none;
}

/* Specific Window Types */
.viewer-page .nav-window {
    top: 20px;
    left: 20px;
    width: 250px;
    height: 400px;
    z-index: 1002;
}

.viewer-page .nav-links {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.viewer-page .nav-links a {
    color: var(--text-light, #D5F6FF);
    text-decoration: none;
    padding: 12px 16px;
    border-radius: 6px;
    background: color-mix(in srgb, var(--primary-color) 20%, transparent);
    transition: all 0.3s;
    border: 1px solid transparent;
    cursor: pointer;
    display: block;
}

.viewer-page .nav-links a:hover {
    background: color-mix(in srgb, var(--primary-color) 35%, transparent);
    border-color: var(--primary-color);
    transform: translateX(4px);
}

.viewer-page .nav-links a.active {
    background: color-mix(in srgb, var(--primary-color) 45%, transparent);
    border-color: var(--primary-color);
    color: var(--surface-base, #031120);
}

.viewer-page .nav-links a[href] {
    pointer-events: auto;
}

.viewer-page .sidebar-nav-title {
    height: 0;
    opacity: 0;
    transition: opacity 0.2s, height 0.2s;
    word-wrap: break-word;
    white-space: normal;
    overflow-wrap: break-word;
}

.viewer-page .nav-btn {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    padding: 6px 10px;
    background: var(--accent-primary-20);
    border: 2px solid var(--primary-color);
    border-radius: 6px;
    color: var(--primary-color);
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.3s ease, opacity 0.2s, height 0.2s;
    white-space: nowrap;
    opacity: 0;
    height: 0;
    overflow: hidden;
}

.viewer-page .nav-btn:hover:not(:disabled) {
    background: var(--accent-primary-35);
    transform: translateY(-2px);
    box-shadow: 0 4px 12px color-mix(in srgb, var(--primary-color) 35%, transparent);
}

.viewer-page .sidebar-nav.is-expanded .sidebar-nav-title,
.viewer-page .sidebar-nav.is-expanded .nav-btn {
    opacity: 1;
    height: auto;
}

.viewer-page .content-window {
    top: 20px;
    left: 290px;
    width: 60%;
    height: 70%;
    z-index: 1001;
}

.viewer-page .content-window iframe {
    width: 100%;
    height: 100%;
    border: none;
    background: transparent;
    overflow-y: auto;
}

.viewer-page .dice-window {
    top: 20px;
    right: 20px;
    width: 400px;
    height: 500px;
    z-index: 1003;

    /* No backdrop blur on the window the dice animate in.
     *
     * `backdrop-filter` makes the browser re-read everything painted behind the
     * window and blur it again whenever the window's contents change. With 3D
     * dice rolling inside, that is sixty backdrop re-blurs a second, on top of
     * the animation itself — which is why the same roll is smoother in a
     * standalone tab, where no such layer exists.
     *
     * Almost nothing is lost: the window background is already 95% opaque, so
     * the blur was only ever showing through the remaining 5%.
     */
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}

.viewer-page .map-window {
    bottom: 20px;
    left: 20px;
    width: 50%;
    height: 40%;
    z-index: 1001;
}

.viewer-page .snap-indicator {
    position: fixed;
    background: color-mix(in srgb, var(--primary-color) 30%, transparent);
    border: 2px solid var(--primary-color);
    border-radius: 8px;
    pointer-events: none;
    z-index: 9998;
    transition: all 0.1s ease;
    box-shadow: 0 0 20px color-mix(in srgb, var(--primary-color) 45%, transparent);
}

/* Combined Widget Container */
.combined-widget-container {
    position: fixed;
    bottom: 20px;
    right: 20px;
    z-index: 9997;
}

/* Combined Widget */
.viewer-page .dice-history-widget {
    position: relative;
    /* It is a pop-out over the campaign, not a sidebar squeezed beside it, so
       it can take the room. Capped against the viewport so it never runs off a
       short window or a narrow one. */
    width: min(420px, calc(100vw - 32px));
    max-height: min(760px, calc(100vh - 140px));
    background: color-mix(in srgb, var(--panel-90) 85%, transparent 15%);
    border: 2px solid color-mix(in srgb, var(--primary-color) 45%, transparent);
    border-radius: 12px;
    backdrop-filter: blur(15px);
    box-shadow: 0 10px 40px color-mix(in srgb, var(--shadow-color) 45%, transparent), 0 0 20px color-mix(in srgb, var(--primary-color) 20%, transparent);
    overflow: hidden;
    animation: slideInFromBottom 0.5s ease-out;
    display: flex;
    flex-direction: column;
    opacity: 1;
    transition: opacity 0.4s ease-out;
}

.combined-widget-header-bar {
    padding: 12px 15px;
    background: linear-gradient(135deg, color-mix(in srgb, var(--primary-color) 25%, transparent), color-mix(in srgb, var(--primary-color) 10%, transparent));
    border-bottom: 2px solid color-mix(in srgb, var(--primary-color) 30%, transparent);
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-shrink: 0;
}

.combined-widget-header-bar h3 {
    margin: 0;
    font-size: 16px;
    color: color-mix(in srgb, var(--primary-color) 75%, var(--text-light) 25%);
    font-weight: 600;
}

.combined-widget-header-actions {
    display: flex;
    align-items: center;
    gap: 8px;
}

.combined-widget-action-btn {
    background: transparent;
    border: none;
    color: color-mix(in srgb, var(--primary-color) 60%, var(--text-light) 40%);
    font-size: 18px;
    cursor: pointer;
    padding: 4px 8px;
    border-radius: 4px;
    transition: all 0.2s ease;
}

.combined-widget-action-btn:hover {
    background: color-mix(in srgb, var(--danger-color, #EC4899) 15%, transparent);
    color: var(--danger-color, #EC4899);
}

.combined-widget-minimize {
    background: transparent;
    border: none;
    color: color-mix(in srgb, var(--primary-color) 60%, var(--text-light) 40%);
    font-size: 20px;
    cursor: pointer;
    padding: 4px 8px;
    border-radius: 4px;
    transition: all 0.2s ease;
    font-weight: bold;
}

.combined-widget-minimize:hover {
    background: color-mix(in srgb, var(--primary-color) 30%, transparent);
    color: color-mix(in srgb, var(--primary-color) 80%, var(--text-light) 20%);
}

#reset-feed-btn {
    font-size: 18px;
    font-weight: bold;
}

/* Unified Feed */
.unified-feed {
    flex: 1;
    overflow-y: auto;
    padding: 8px 6px;
    display: flex;
    flex-direction: column;
    /* Rows sit close together; the avatar and the name do the separating. */
    gap: 2px;
    min-height: 0;
}

.unified-feed .no-content {
    color: rgba(255, 255, 255, 0.5);
    text-align: center;
    padding: 40px 20px;
    font-style: italic;
    margin: auto;
}

/* Shared Users Menu */
.shared-users-menu {
    margin-top: auto;
    border-top: 1px solid color-mix(in srgb, var(--primary-color) 30%, transparent);
    padding-top: 10px;
}

.shared-users-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 16px;
    color: rgba(255, 255, 255, 0.75);
    cursor: pointer;
    transition: all 0.2s;
    white-space: nowrap;
    font-size: 0.9em;
    font-weight: 500;
}

.sidebar-nav.is-expanded .shared-users-header {
    opacity: 1;
}

.shared-users-header:hover {
    color: var(--primary-color);
    background: color-mix(in srgb, var(--primary-color) 20%, transparent 80%);
}

.shared-users-header h3 {
    margin: 0;
    font-size: 0.9em;
    opacity: 0;
    transition: opacity 0.2s;
}

.sidebar-nav.is-expanded .shared-users-header h3 {
    opacity: 1;
}

.shared-users-toggle {
    font-size: 12px;
    opacity: 0;
    transition: opacity 0.2s, transform 0.2s;
}

.sidebar-nav.is-expanded .shared-users-toggle {
    opacity: 1;
}

.shared-users-list {
    max-height: 300px;
    overflow-y: auto;
    transition: max-height 0.3s ease-out, opacity 0.2s;
    opacity: 1;
}

.shared-users-list.collapsed {
    max-height: 0;
    overflow: hidden;
    opacity: 0;
}

.shared-user-item {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    padding: 8px 16px 8px 36px;
    color: rgba(255, 255, 255, 0.65);
    font-size: 0.85em;
    white-space: nowrap;
    opacity: 1;
    gap: 8px;
}

.shared-user-item > span {
    flex: 1;
    min-width: 0;
}

.shared-user-name {
    font-weight: 500;
}

.shared-user-role {
    font-size: 0.8em;
    color: rgba(255, 255, 255, 0.5);
    margin-top: 2px;
}

/* Ownership transfer (S-16 FR-13) */
.btn-offer-owner,
.btn-withdraw-offer {
    padding: 2px 8px;
    border: 1px solid color-mix(in srgb, var(--primary-color) 50%, transparent);
    border-radius: 4px;
    background: transparent;
    color: var(--text-light);
    font-size: 0.75em;
    cursor: pointer;
    white-space: nowrap;
}

.btn-offer-owner:hover,
.btn-withdraw-offer:hover {
    background: color-mix(in srgb, var(--primary-color) 20%, transparent);
}

.ownership-offer-pending {
    margin-top: 8px;
    padding: 6px 8px;
    border-left: 3px solid var(--primary-color);
    font-size: 0.8em;
    color: var(--text-light);
}

/* Online Users Section */
.online-users-section {
    border-bottom: 1px solid color-mix(in srgb, var(--primary-color) 25%, transparent);
    background: color-mix(in srgb, var(--surface-base) 60%, transparent 40%);
    padding: 10px;
    flex-shrink: 0;
}

.online-users-header {
    font-size: 0.68em;
    color: rgba(255, 255, 255, 0.42);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .07em;
    margin-bottom: 6px;
    padding: 0 4px;
}

.online-users-list {
    display: flex;
    flex-direction: column;
    gap: 1px;
    max-height: 132px;
    overflow-y: auto;
}

/* A row, not a pill. Two people used to take as much height as five feed
   items, because every name sat in its own filled capsule. */
.online-user-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 3px 4px;
    border-radius: 6px;
    font-size: 0.85em;
}

.online-user-name {
    flex: 1;
    min-width: 0;
    color: rgba(255, 255, 255, 0.5);
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Being at the table reads brighter than having left it. */
.online-user-item.is-online .online-user-name {
    color: rgba(255, 255, 255, 0.88);
}

.online-user-status-text {
    flex-shrink: 0;
    font-size: 0.72em;
    color: rgba(255, 255, 255, 0.32);
}

/* Feed Item
   A row, not a card. Three of these used to fill the whole panel: each had a
   background, a coloured left border, a shadow and a hover slide, so the
   chrome outweighed the sentence inside it. Same shape as a direct message
   now — avatar, who and when, then what they said. */
.feed-item {
    display: flex;
    gap: 8px;
    padding: 6px 4px;
    border-radius: 8px;
}

.feed-item:hover {
    background: color-mix(in srgb, var(--primary-color) 8%, transparent);
}

.feed-item-body {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.feed-item-head {
    display: flex;
    align-items: baseline;
    gap: 8px;
}

.feed-item-author {
    flex: 1;
    min-width: 0;
    font-weight: 600;
    font-size: 0.78em;
    color: rgba(255, 255, 255, 0.8);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.feed-item-time {
    flex-shrink: 0;
    font-size: 0.68em;
    color: rgba(255, 255, 255, 0.3);
}

.feed-item-text {
    font-size: 0.85em;
    line-height: 1.4;
    color: rgba(255, 255, 255, 0.9);
    word-break: break-word;
}

.feed-item-text.is-log {
    white-space: pre-wrap;
}

/* Edit / Delete / Remove / Report on a chat message (S-48 FR-8 to FR-10).
   Out of the way until the row is hovered or focused: they are for the odd
   moment, not part of reading the conversation. */
.feed-item-actions {
    display: flex;
    gap: 6px;
    opacity: 0;
    transition: opacity 0.12s ease;
}

.feed-item:hover .feed-item-actions,
.feed-item:focus-within .feed-item-actions {
    opacity: 1;
}

@media (hover: none) {
    .feed-item-actions { opacity: 1; }
}

.feed-item-actions[hidden] {
    display: none;
}

.feed-item-action {
    padding: 1px 7px;
    border: 1px solid color-mix(in srgb, var(--primary-color) 25%, transparent);
    border-radius: 5px;
    background: none;
    color: rgba(255, 255, 255, 0.55);
    font-size: 0.68em;
    cursor: pointer;
}

.feed-item-action:hover,
.feed-item-action:focus-visible {
    color: #fff;
    background: color-mix(in srgb, var(--primary-color) 15%, transparent);
}

.feed-item-action.is-danger:hover,
.feed-item-action.is-danger:focus-visible {
    border-color: var(--danger-color, #e06c6c);
    background: color-mix(in srgb, var(--danger-color, #e06c6c) 25%, transparent);
}

.feed-item-edited,
.dm-edited {
    flex-shrink: 0;
    font-size: 0.66em;
    font-style: italic;
    color: rgba(255, 255, 255, 0.4);
}

.feed-item-text.is-deleted,
.dm-bubble.is-deleted {
    font-style: italic;
    color: rgba(255, 255, 255, 0.4);
}

/* Edit / Delete on your own direct message, inside the bubble. */
.dm-bubble-actions {
    display: none;
    gap: 4px;
    margin-left: 8px;
    vertical-align: middle;
}

.dm-bubble:hover .dm-bubble-actions,
.dm-bubble:focus-within .dm-bubble-actions {
    display: inline-flex;
}

@media (hover: none) {
    .dm-bubble-actions { display: inline-flex; }
}

.dm-bubble-action {
    padding: 0 6px;
    border: 1px solid color-mix(in srgb, var(--primary-color) 30%, transparent);
    border-radius: 5px;
    background: none;
    color: rgba(255, 255, 255, 0.6);
    font-size: 0.72em;
    cursor: pointer;
}

.dm-bubble-action:hover,
.dm-bubble-action:focus-visible {
    color: #fff;
    background: color-mix(in srgb, var(--primary-color) 20%, transparent);
}

.dm-bubble-action.is-danger:hover,
.dm-bubble-action.is-danger:focus-visible {
    border-color: var(--danger-color, #e06c6c);
    background: color-mix(in srgb, var(--danger-color, #e06c6c) 25%, transparent);
}

.dm-edit {
    display: flex;
    gap: 4px;
    align-items: center;
    min-width: 220px;
}

.dm-edited {
    margin-left: 4px;
}

.feed-item-edit {
    display: flex;
    gap: 6px;
    align-items: center;
}

.feed-item-edit input,
.dm-edit input {
    flex: 1;
    min-width: 0;
    padding: 5px 8px;
    border-radius: 6px;
    border: 1px solid var(--border-color);
    background: var(--surface-base);
    color: var(--text-light);
    font-size: 0.85em;
}

/* A roll is a notation and a number, and the number is what anyone reads —
   so it gets the weight rather than being small print under the notation. */
.feed-item-roll-line {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 0.85em;
}

.feed-item-notation {
    color: rgba(255, 255, 255, 0.85);
    font-variant-numeric: tabular-nums;
}

.feed-item-dice {
    flex: 1;
    min-width: 0;
    color: rgba(255, 255, 255, 0.38);
    font-size: 0.85em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.feed-item-total {
    flex-shrink: 0;
    min-width: 26px;
    padding: 1px 8px;
    border-radius: 10px;
    background: color-mix(in srgb, var(--primary-color) 28%, transparent);
    color: #fff;
    font-weight: 700;
    text-align: center;
    font-variant-numeric: tabular-nums;
}

.feed-item-reactions {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
    margin-top: 8px;
    padding-top: 8px;
    border-top: 1px solid color-mix(in srgb, var(--primary-color) 20%, transparent);
}

.reaction-btn {
    background: color-mix(in srgb, var(--primary-color) 20%, transparent);
    border: 1px solid color-mix(in srgb, var(--primary-color) 40%, transparent);
    border-radius: 12px;
    padding: 4px 8px;
    font-size: 12px;
    cursor: pointer;
    transition: all 0.2s ease;
    display: flex;
    align-items: center;
    gap: 4px;
    color: var(--text-light);
}

.reaction-btn:hover {
    background: color-mix(in srgb, var(--primary-color) 30%, transparent);
    border-color: var(--primary-color);
    transform: scale(1.05);
}

.reaction-btn.active {
    background: color-mix(in srgb, var(--primary-color) 40%, transparent);
    border-color: var(--primary-color);
}

.reaction-count {
    font-weight: 600;
    font-size: 11px;
}

.viewer-page .dice-history-widget.collapsed:not(.fading-out) {
    display: none;
}

.viewer-page .dice-history-widget.fading-out {
    opacity: 0 !important;
    pointer-events: none;
    /* Keep display: flex during fade so transition is visible */
    display: flex !important;
}

.viewer-page .dice-history-toggle {
    position: relative;
    bottom: auto;
    right: auto;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 10px 16px;
    background: color-mix(in srgb, var(--panel-90) 85%, transparent 15%);
    border: 2px solid color-mix(in srgb, var(--primary-color) 45%, transparent);
    border-radius: 999px;
    color: color-mix(in srgb, var(--primary-color) 70%, var(--text-light) 30%);
    font-weight: 600;
    cursor: pointer;
    box-shadow: 0 8px 30px color-mix(in srgb, var(--shadow-color) 45%, transparent);
    backdrop-filter: blur(12px);
    z-index: 9997;
    transition: transform 0.2s, box-shadow 0.2s, background 0.2s;
}

.viewer-page .dice-history-toggle:hover {
    transform: translateY(-2px);
    box-shadow: 0 12px 35px color-mix(in srgb, var(--shadow-color) 55%, transparent);
    background: color-mix(in srgb, var(--panel-90) 90%, transparent 10%);
}

.viewer-page .dice-history-toggle.hidden {
    display: none;
}

.viewer-page .dice-history-toggle-count {
    display: none;
    min-width: 20px;
    padding: 2px 6px;
    border-radius: 999px;
    background: color-mix(in srgb, var(--accent-color) 35%, transparent);
    color: color-mix(in srgb, var(--accent-color) 70%, var(--text-light) 30%);
    font-size: 12px;
    font-weight: 700;
    text-align: center;
}

.combined-widget-close {
    padding: 4px 8px;
    background: transparent;
    border: none;
    color: color-mix(in srgb, var(--primary-color) 60%, var(--text-light) 40%);
    font-size: 20px;
    cursor: pointer;
    transition: all 0.2s ease;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 4px;
}

.combined-widget-close:hover {
    background: color-mix(in srgb, var(--danger-color, #EC4899) 15%, transparent);
    color: var(--danger-color, #EC4899);
}

.viewer-page .dice-history-title {
    display: flex;
    align-items: center;
    gap: 8px;
}

.viewer-page .dice-history-header h3 {
    margin: 0;
    font-size: 16px;
    color: color-mix(in srgb, var(--primary-color) 75%, var(--text-light) 25%);
    font-weight: 600;
    letter-spacing: 0.5px;
}

.viewer-page .dice-history-actions {
    display: flex;
    align-items: center;
    gap: 8px;
}

.viewer-page .collapse-history-btn,
.viewer-page .clear-history-btn {
    background: none;
    border: none;
    color: rgba(255, 255, 255, 0.7);
    font-size: 22px;
    line-height: 1;
    cursor: pointer;
    padding: 0;
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.2s;
    border-radius: 4px;
}

.viewer-page .collapse-history-btn:hover {
    background: color-mix(in srgb, var(--primary-color) 25%, transparent);
    color: color-mix(in srgb, var(--primary-color) 80%, var(--text-light) 20%);
}

.viewer-page .clear-history-btn {
    font-size: 24px;
}

.viewer-page .clear-history-btn:hover {
    background: rgba(255, 100, 100, 0.2);
    color: #ff6b6b;
}

.viewer-page .dice-history-list {
    padding: 10px;
    max-height: 340px;
    overflow-y: auto;
    overscroll-behavior: contain;
}

.viewer-page .dice-history-list::-webkit-scrollbar {
    width: 8px;
}

.viewer-page .dice-history-list::-webkit-scrollbar-track {
    background: rgba(0, 0, 0, 0.2);
    border-radius: 4px;
}

.viewer-page .dice-history-list::-webkit-scrollbar-thumb {
    background: color-mix(in srgb, var(--primary-color) 35%, transparent);
    border-radius: 4px;
}

.viewer-page .dice-history-list::-webkit-scrollbar-thumb:hover {
    background: color-mix(in srgb, var(--primary-color) 55%, transparent);
}

.viewer-page .no-rolls {
    text-align: center;
    color: rgba(255, 255, 255, 0.5);
    font-size: 14px;
    font-style: italic;
    padding: 20px;
}

.viewer-page .dice-roll-item {
    background: color-mix(in srgb, var(--surface-panel) 85%, transparent 15%);
    border: 1px solid color-mix(in srgb, var(--primary-color) 25%, transparent);
    border-radius: 8px;
    padding: 10px 12px;
    margin-bottom: 8px;
    animation: rollAppear 0.3s ease-out;
}

.viewer-page .dice-roll-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 6px;
}

.viewer-page .dice-roll-player {
    font-size: 12px;
    color: var(--abyssal-teal);
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.viewer-page .dice-roll-notation {
    font-size: 13px;
    color: color-mix(in srgb, var(--primary-color) 70%, var(--text-light) 30%);
    font-weight: 600;
    margin-bottom: 4px;
}

.viewer-page .dice-roll-result {
    font-size: 14px;
    color: #fff;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.viewer-page .dice-roll-values {
    color: rgba(255, 255, 255, 0.8);
}

.viewer-page .dice-roll-total {
    font-size: 16px;
    font-weight: bold;
    color: var(--abyssal-glow);
}

.viewer-page .dice-roll-timestamp {
    font-size: 11px;
    color: rgba(255, 255, 255, 0.4);
}

/* Chat Widget */
.viewer-page .chat-widget {
    position: fixed;
    bottom: 20px;
    right: 20px;
    width: 320px;
    z-index: 9996;
    animation: bubbleFloat 3s ease-in-out infinite;
}

.viewer-page .chat-widget.collapsed .chat-panel {
    display: none;
}

.viewer-page .chat-toggle {
    background: linear-gradient(135deg, color-mix(in srgb, var(--primary-color) 70%, transparent), color-mix(in srgb, var(--accent-color) 70%, transparent));
    border: 2px solid color-mix(in srgb, var(--primary-color) 55%, transparent);
    border-radius: 20px;
    padding: 8px 16px;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 6px;
    box-shadow: 0 3px 15px color-mix(in srgb, var(--shadow-color) 45%, transparent), 0 0 20px color-mix(in srgb, var(--primary-color) 25%, transparent);
    transition: all 0.3s ease;
    font-weight: 600;
    font-size: 13px;
    color: white;
    backdrop-filter: blur(10px);
}

.viewer-page .chat-toggle:hover {
    transform: translateY(-2px);
    box-shadow: 0 5px 25px color-mix(in srgb, var(--shadow-color) 55%, transparent), 0 0 30px color-mix(in srgb, var(--primary-color) 35%, transparent);
    border-color: color-mix(in srgb, var(--primary-color) 70%, transparent);
    background: linear-gradient(135deg, color-mix(in srgb, var(--primary-color) 80%, transparent), color-mix(in srgb, var(--accent-color) 80%, transparent));
}

.viewer-page .chat-unread {
    background: var(--accent-color);
    color: var(--text-light);
    border-radius: 50%;
    padding: 2px 6px;
    font-size: 11px;
    font-weight: bold;
    min-width: 18px;
    text-align: center;
}

.viewer-page .chat-panel {
    width: 100%;
    max-height: 400px;
    background: color-mix(in srgb, var(--panel-90) 85%, transparent 15%);
    border: 2px solid color-mix(in srgb, var(--primary-color) 45%, transparent);
    border-radius: 20px;
    box-shadow: 0 10px 40px color-mix(in srgb, var(--shadow-color) 45%, transparent), 0 0 30px color-mix(in srgb, var(--primary-color) 20%, transparent);
    flex-direction: column;
    backdrop-filter: blur(15px);
    margin-top: 10px;
    animation: bubbleExpand 0.3s ease-out;
}

.viewer-page .chat-header {
    padding: 12px 15px;
    background: linear-gradient(135deg, color-mix(in srgb, var(--primary-color) 30%, transparent), color-mix(in srgb, var(--accent-color) 25%, transparent));
    border-bottom: 2px solid color-mix(in srgb, var(--primary-color) 35%, transparent);
    border-radius: 20px 20px 0 0;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.viewer-page .chat-header h3 {
    margin: 0;
    font-size: 16px;
    color: color-mix(in srgb, var(--primary-color) 75%, var(--text-light) 25%);
    font-weight: 600;
}

.viewer-page .chat-close {
    background: none;
    border: none;
    color: rgba(255, 255, 255, 0.6);
    font-size: 24px;
    cursor: pointer;
    padding: 0;
    width: 30px;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.viewer-page .chat-close:hover {
    color: white;
}

.viewer-page .chat-messages,
#chat-section .chat-messages,
.combined-widget-list.chat-messages {
    flex: 1;
    overflow-y: auto;
    padding: 10px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.viewer-page .chat-messages::-webkit-scrollbar {
    width: 8px;
}

.viewer-page .chat-messages::-webkit-scrollbar-track {
    background: rgba(0, 0, 0, 0.2);
    border-radius: 4px;
}

.viewer-page .chat-messages::-webkit-scrollbar-thumb {
    background: color-mix(in srgb, var(--primary-color) 35%, transparent);
    border-radius: 4px;
}

.viewer-page .chat-messages::-webkit-scrollbar-thumb:hover {
    background: color-mix(in srgb, var(--primary-color) 55%, transparent);
}

.viewer-page .no-messages {
    color: rgba(255, 255, 255, 0.5);
    text-align: center;
    padding: 20px;
    font-style: italic;
}

.viewer-page .chat-message {
    background: color-mix(in srgb, var(--primary-color) 15%, transparent);
    padding: 10px;
    border-radius: 12px;
    border-left: 3px solid color-mix(in srgb, var(--primary-color) 65%, transparent);
    box-shadow: 0 2px 8px color-mix(in srgb, var(--primary-color) 20%, transparent);
}

.viewer-page .chat-message.own-message {
    background: color-mix(in srgb, var(--accent-color) 20%, transparent);
    border-left-color: color-mix(in srgb, var(--accent-color) 70%, transparent);
    box-shadow: 0 2px 8px color-mix(in srgb, var(--accent-color) 25%, transparent);
}

.viewer-page .chat-message-header {
    display: flex;
    justify-content: space-between;
    margin-bottom: 5px;
    font-size: 12px;
}

.viewer-page .chat-message-author {
    font-weight: 600;
    color: color-mix(in srgb, var(--accent-color) 70%, var(--text-light) 30%);
}

.viewer-page .chat-message.own-message .chat-message-author {
    color: var(--accent-color);
}

.viewer-page .chat-message-time {
    color: rgba(255, 255, 255, 0.5);
}

.viewer-page .chat-message-text {
    color: var(--text-light);
    word-wrap: break-word;
    line-height: 1.4;
}

.viewer-page .chat-input-container {
    padding: 15px;
    border-top: 2px solid color-mix(in srgb, var(--primary-color) 25%, transparent);
    display: flex;
    gap: 10px;
    background: color-mix(in srgb, var(--surface-base) 80%, transparent 20%);
    border-radius: 0 0 20px 20px;
}

.viewer-page .chat-input-container input {
    flex: 1;
    background: color-mix(in srgb, var(--surface-panel) 90%, transparent 10%);
    border: 2px solid color-mix(in srgb, var(--primary-color) 30%, transparent);
    border-radius: 15px;
    padding: 10px 15px;
    color: var(--text-light);
    font-size: 14px;
}

.viewer-page .chat-input-container input:focus {
    outline: none;
    border-color: color-mix(in srgb, var(--primary-color) 60%, transparent);
    box-shadow: 0 0 10px color-mix(in srgb, var(--primary-color) 35%, transparent);
}

.viewer-page .chat-send-btn {
    background: linear-gradient(135deg, color-mix(in srgb, var(--primary-color) 80%, transparent), color-mix(in srgb, var(--accent-color) 80%, transparent));
    border: none;
    border-radius: 15px;
    padding: 10px 20px;
    color: white;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.3s ease;
    box-shadow: 0 2px 10px color-mix(in srgb, var(--primary-color) 30%, transparent);
}

.viewer-page .chat-send-btn:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 15px color-mix(in srgb, var(--primary-color) 45%, transparent);
    background: linear-gradient(135deg, color-mix(in srgb, var(--primary-color) 90%, transparent), color-mix(in srgb, var(--accent-color) 90%, transparent));
}

/* Responsive adjustments */
@media (max-width: 1024px) {
    .viewer-page .nav-window {
        width: 220px;
        height: 350px;
    }

    .viewer-page .content-window {
        left: 250px;
        width: calc(100% - 270px);
    }

    .viewer-page .dice-window {
        width: 350px;
        height: 450px;
    }

    .viewer-page .map-window {
        width: calc(100% - 40px);
        height: 35%;
    }
}

@media (max-width: 768px) {
    .viewer-page .window {
        min-width: 280px;
        min-height: 180px;
    }

    .viewer-page .nav-window {
        width: 100%;
        height: auto;
        top: 10px;
        left: 10px;
        right: 10px;
        max-height: 200px;
    }

    .viewer-page .content-window {
        top: 220px;
        left: 10px;
        right: 10px;
        width: auto;
        height: calc(100vh - 240px);
    }

    .viewer-page .dice-window {
        width: 300px;
        height: 300px;
        top: auto;
        bottom: 10px;
        right: 10px;
    }

    .viewer-page .map-window {
        width: auto;
        bottom: 320px;
        left: 10px;
        right: 10px;
        height: calc(100vh - 340px);
    }
}

@media (max-width: 480px) {
    .viewer-page .window {
        min-width: 260px;
        min-height: 160px;
    }

    .viewer-page .nav-window {
        height: auto;
        max-height: 150px;
    }

    .viewer-page .content-window {
        top: 170px;
        height: calc(100vh - 190px);
    }

    .viewer-page .dice-window {
        width: 280px;
        height: 280px;
        bottom: 5px;
        right: 5px;
    }

    .viewer-page .map-window {
        bottom: 295px;
        height: calc(100vh - 315px);
    }

    .viewer-page .window-header {
        padding: 6px 10px;
        font-size: 12px;
    }

    .viewer-page .window-control {
        width: 18px;
        height: 18px;
        font-size: 10px;
    }

    .viewer-page .window-content,
.window-content {
        padding: 12px;
    }
}

/* ============================================================================
   CAMPAIGN FEED — Feed / Direct tabs
   The feed panel holds what was always there; the direct panel is one
   conversation at a time with someone at the table or on your friends list.
   ============================================================================ */

.feed-tabs {
    display: flex;
    flex-shrink: 0;
    border-bottom: 1px solid color-mix(in srgb, var(--primary-color) 25%, transparent);
    background: color-mix(in srgb, var(--surface-base) 60%, transparent 40%);
}

.feed-tab {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    padding: 9px 8px;
    background: none;
    border: none;
    border-bottom: 2px solid transparent;
    color: rgba(255, 255, 255, 0.6);
    font-size: 0.85em;
    font-weight: 500;
    cursor: pointer;
}

.feed-tab:hover {
    color: rgba(255, 255, 255, 0.85);
    background: color-mix(in srgb, var(--primary-color) 10%, transparent);
}

.feed-tab.active {
    color: #fff;
    border-bottom-color: var(--primary-color);
}

.feed-tab-badge {
    min-width: 17px;
    padding: 1px 5px;
    border-radius: 9px;
    background: var(--danger-color, #e06c6c);
    color: #fff;
    font-size: 0.7em;
    font-weight: bold;
    line-height: 1.5;
}

/* Each panel fills what is left of the widget, and scrolls inside itself. */
.feed-tab-panel {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
}

.feed-tab-panel[hidden] {
    display: none;
}


/* ---- Direct: shared pieces ---- */

/* A monogram stands in for a picture. The hue comes from the name (see
   avatar() in direct-messages.js) so the same person is the same colour
   everywhere, which is what makes a list scannable without photographs. */
.dm-avatar {
    flex-shrink: 0;
    position: relative;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 0.72em;
    font-weight: 700;
    letter-spacing: .02em;
    color: #fff;
    background: hsl(var(--dm-avatar-hue, 200) 45% 42%);
    text-transform: uppercase;
}

/* Presence rides on the avatar rather than taking a column of its own. */
.dm-avatar.is-online::after {
    content: '';
    position: absolute;
    right: -1px;
    bottom: -1px;
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: #43c86a;
    border: 2px solid var(--surface-base, #0b1a2a);
}

/* ---- Direct: the people you can talk to ---- */

.dm-people {
    flex: 1;
    overflow-y: auto;
    padding: 6px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    /* A floor, so the widget does not shrink to one row and then jump back
       when the Feed tab is selected. The widget's own max-height caps it. */
    min-height: 240px;
}

.dm-people[hidden] {
    display: none;
}

.dm-people .no-content {
    color: rgba(255, 255, 255, 0.5);
    text-align: center;
    padding: 30px 20px;
    font-style: italic;
    margin: auto;
}

.dm-person {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 8px 10px;
    background: none;
    border: none;
    border-radius: 8px;
    color: inherit;
    text-align: left;
    cursor: pointer;
}

.dm-person:hover {
    background: color-mix(in srgb, var(--primary-color) 14%, transparent);
}

/* The row has to survive a long username: the name and the preview both
   truncate, and the time and unread pill keep their space. */
.dm-person-main {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}

.dm-person-top,
.dm-person-bottom {
    display: flex;
    align-items: baseline;
    gap: 8px;
}

.dm-person-name {
    flex: 1;
    min-width: 0;
    color: rgba(255, 255, 255, 0.88);
    font-size: 0.88em;
    font-weight: 500;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dm-person-when {
    flex-shrink: 0;
    color: rgba(255, 255, 255, 0.35);
    font-size: 0.7em;
}

.dm-person-preview {
    flex: 1;
    min-width: 0;
    color: rgba(255, 255, 255, 0.45);
    font-size: 0.78em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dm-person.has-unread .dm-person-name {
    color: #fff;
    font-weight: 600;
}

.dm-person.has-unread .dm-person-preview {
    color: rgba(255, 255, 255, 0.75);
}

.dm-person-unread {
    flex-shrink: 0;
    min-width: 18px;
    padding: 1px 6px;
    border-radius: 9px;
    background: var(--primary-color);
    color: var(--surface-base, #06131f);
    font-size: 0.7em;
    font-weight: 700;
    text-align: center;
}

/* ---- Direct: one conversation ---- */

.dm-thread {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
}

.dm-thread[hidden] {
    display: none;
}

.dm-thread-header {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
    padding: 8px 10px;
    border-bottom: 1px solid color-mix(in srgb, var(--primary-color) 25%, transparent);
}

.dm-back {
    background: none;
    border: none;
    color: rgba(255, 255, 255, 0.7);
    font-size: 1.1em;
    cursor: pointer;
    padding: 0 4px;
}

.dm-back:hover {
    color: #fff;
}

.dm-with {
    font-weight: 600;
    color: rgba(255, 255, 255, 0.9);
    font-size: 0.9em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.dm-messages {
    flex: 1;
    overflow-y: auto;
    padding: 10px;
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-height: 240px;
}

.dm-messages .no-content {
    color: rgba(255, 255, 255, 0.5);
    text-align: center;
    padding: 30px 20px;
    font-style: italic;
    margin: auto;
}

/* A hairline with the day sitting in it. */
.dm-day {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 10px 0 6px;
    color: rgba(255, 255, 255, 0.35);
    font-size: 0.7em;
    text-transform: uppercase;
    letter-spacing: .06em;
}

.dm-day::before,
.dm-day::after {
    content: '';
    flex: 1;
    height: 1px;
    background: color-mix(in srgb, var(--primary-color) 20%, transparent);
}

/* A run of messages from one person: avatar and name once, bubbles after. */
.dm-group {
    display: flex;
    gap: 8px;
    margin-top: 8px;
}

.dm-group.mine {
    justify-content: flex-end;
}

.dm-group-body {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    max-width: 78%;
}

.dm-group.mine .dm-group-body {
    align-items: flex-end;
}

.dm-group-head {
    display: flex;
    align-items: baseline;
    gap: 6px;
    padding: 0 2px;
}

.dm-group-name {
    color: rgba(255, 255, 255, 0.8);
    font-size: 0.78em;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 180px;
}

.dm-group-time {
    color: rgba(255, 255, 255, 0.3);
    font-size: 0.68em;
}

.dm-bubble {
    padding: 7px 11px;
    border-radius: 14px;
    font-size: 0.85em;
    line-height: 1.4;
    color: rgba(255, 255, 255, 0.92);
    word-break: break-word;
    white-space: pre-wrap;
}

.dm-group.theirs .dm-bubble {
    background: color-mix(in srgb, var(--surface-base) 85%, transparent);
    border-bottom-left-radius: 5px;
}

.dm-group.mine .dm-bubble {
    background: color-mix(in srgb, var(--primary-color) 32%, transparent);
    border-bottom-right-radius: 5px;
}

/* Only the last bubble in a run gets the tail; the rest stay rounded, which
   is what makes a run read as one turn rather than several. */
.dm-group.theirs .dm-bubble:not(:last-child) {
    border-bottom-left-radius: 14px;
}

.dm-group.mine .dm-bubble:not(:last-child) {
    border-bottom-right-radius: 14px;
}

/* The small avatar used in dense lists — the feed and the presence rows. */
.dm-avatar.is-small {
    width: 24px;
    height: 24px;
    font-size: 0.62em;
}

.dm-avatar.is-small.is-online::after {
    width: 8px;
    height: 8px;
    border-width: 2px;
}

/* Block / Report, in the conversation header. Quiet until wanted — they are
   there for a bad moment, not part of the everyday furniture. */
.dm-thread-action {
    flex-shrink: 0;
    padding: 3px 8px;
    border: 1px solid color-mix(in srgb, var(--primary-color) 25%, transparent);
    border-radius: 6px;
    background: none;
    color: rgba(255, 255, 255, 0.45);
    font-size: 0.7em;
    cursor: pointer;
}

.dm-thread-action:hover {
    color: rgba(255, 255, 255, 0.9);
    background: color-mix(in srgb, var(--primary-color) 15%, transparent);
}

.dm-thread-action.is-danger:hover {
    color: #fff;
    border-color: var(--danger-color, #e06c6c);
    background: color-mix(in srgb, var(--danger-color, #e06c6c) 25%, transparent);
}

/* Campaign Settings — Combat Cards section (S-38 FR-13). The preview card
   itself is styled by the tracker's .ct-tcg rules; these lay out the form. */
.combat-cards-settings-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 20px;
    align-items: start;
}

@media (max-width: 720px) {
    .combat-cards-settings-layout {
        grid-template-columns: minmax(0, 1fr);
    }
}

.combat-cards-fieldset {
    border: 0;
    padding: 0;
    margin: 0 0 12px;
}

.combat-cards-fieldset legend {
    margin-bottom: 6px;
    color: var(--text-light);
    font-weight: 600;
}

.combat-cards-choice {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 4px 0;
    cursor: pointer;
}

.combat-cards-art-source {
    margin-bottom: 6px;
    color: var(--text-dim);
    font-size: 13px;
}

.combat-cards-settings-controls input[type="range"] {
    width: 100%;
}

.combat-card-preview {
    justify-self: center;
}


/* pages/_combat-tracker.css */
/**
 * Combat Tracker Styles - TCG (Trading Card Game) Layout
 * Simplified, unified styles for compact Magic: The Gathering-style cards
 */

/* ============================================================================
   CARD LAYOUT - TCG Style
   ============================================================================ */

.combat-carousel .item-card {
    flex: 0 0 280px;
    min-width: 280px;
    max-width: 280px;
    display: flex;
    flex-direction: column;
    transition: transform 0.3s ease, box-shadow 0.3s ease;
    border: 1px solid var(--primary-color);
    border-radius: 6px;
    overflow: hidden;
    background: var(--panel-75);
}

.combat-carousel .item-card.current-turn {
    border: 3px solid var(--primary-color);
    box-shadow: 0 0 20px color-mix(in srgb, var(--primary-color) 60%, transparent);
    transform: scale(1.05);
    z-index: 10;
    position: relative;
}

/* Active dice tray indicator - matches combat tracker current-turn styling */
.combat-carousel .item-card.dice-tray-active {
    border: 3px solid var(--primary-color);
    box-shadow: 0 0 20px color-mix(in srgb, var(--primary-color) 60%, transparent);
    transform: scale(1.05);
    z-index: 10;
    position: relative;
    transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.open-dice-tray-btn.active {
    background: color-mix(in srgb, var(--accent-color) 15%, transparent);
    border: 2px solid var(--accent-color);
    box-shadow: 0 0 10px color-mix(in srgb, var(--accent-color) 50%, transparent);
}

.combat-card-wrapper {
    display: flex;
    flex-direction: column;
    height: 100%;
}

/* ============================================================================
   CARD HEADER - Top Title Bar (Like MTG Name Bar)
   ============================================================================ */

.combat-card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 4px 6px;
    background: color-mix(in srgb, var(--primary-color) 20%, transparent);
    border-bottom: 2px solid var(--primary-color);
    flex-shrink: 0;
}

.combat-card-header-left {
    display: flex;
    flex-direction: column;
    gap: 1px;
    flex: 1;
    min-width: 0;
}

.combat-card-title-wrapper {
    color: var(--primary-color);
    margin: 0;
    font-size: 0.9em;
    font-weight: 700;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.combat-card-title-wrapper .current-turn-indicator {
    color: var(--accent-color);
    font-size: 0.85em;
}

.combat-card-title-wrapper .rage-indicator {
    color: var(--danger-color, #ff4444);
    font-size: 0.85em;
    font-weight: 700;
}

.combat-card-meta {
    display: flex;
    gap: 6px;
    align-items: center;
    font-size: 0.65em;
    color: var(--text-light);
    opacity: 0.8;
    flex-wrap: wrap;
}

.combat-stat-inline {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    margin-left: 2px;
}

.combat-stat-label-inline {
    font-size: 0.65em;
    opacity: 0.7;
}

.combat-stat-value-inline {
    font-weight: 600;
    font-size: 0.7em;
}

/* HP color styling for inline stats */
.combat-stat-inline[data-hp-color="critical"] .combat-stat-value-inline {
    color: #ff4444;
}

.combat-stat-inline[data-hp-color="warning"] .combat-stat-value-inline {
    color: #ff8844;
}

.combat-stat-inline[data-hp-color="healthy"] .combat-stat-value-inline {
    color: var(--primary-color);
}

.combat-stat-inline[data-hp-color="dead"] .combat-stat-value-inline {
    color: #666;
}

.combat-card-header-right {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
    margin-left: 6px;
    position: relative;
}

.combat-stat-group-header {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    gap: 1px;
    min-height: 0;
}

.combat-stat-group-header > .combat-initiative-input-wrapper {
    display: flex;
    align-items: center;
    gap: 2px;
}

.combat-initiative-label {
    color: var(--text-light);
    font-size: 0.55em;
    opacity: 0.7;
}

.combat-initiative-value {
    color: var(--primary-color);
    font-size: 1em;
    font-weight: 700;
}

/* HP color styling for initiative-style values */
.combat-initiative-value[data-hp-color="critical"] {
    color: #ff4444;
}

.combat-initiative-value[data-hp-color="warning"] {
    color: #ff8844;
}

.combat-initiative-value[data-hp-color="healthy"] {
    color: var(--primary-color);
}

.combat-initiative-value[data-hp-color="dead"] {
    color: #666;
}

/* AC modified styling for initiative-style values */
.combat-initiative-value[data-ac-modified="true"] {
    color: var(--accent-color);
}

.combat-initiative-value.editable-initiative {
    cursor: pointer;
    user-select: none;
    transition: opacity 0.2s ease;
    padding: 0;
    border-radius: 3px;
}

.combat-initiative-value.editable-initiative:hover {
    background: color-mix(in srgb, var(--primary-color) 20%, transparent);
    opacity: 0.8;
}

.combat-initiative-value.editable-initiative.dash {
    color: var(--text-light);
    opacity: 0.5;
    font-size: 1.2em;
}

.combat-initiative-value.editable-initiative.dash:hover {
    opacity: 1;
    color: var(--primary-color);
}

/* Initiative Input Overlay */
.initiative-input-overlay {
    display: none;
    position: absolute;
    top: calc(100% + 4px);
    left: 50%;
    transform: translateX(-50%);
    z-index: 1000;
    background: color-mix(in srgb, var(--surface-panel) 98%, transparent);
    border: 2px solid var(--primary-color);
    border-radius: 4px;
    padding: 6px 8px;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.5);
    gap: 4px;
    align-items: center;
}

.initiative-input-overlay.show {
    display: flex;
}

.initiative-input-overlay input {
    width: 50px;
    padding: 4px 6px;
    background: color-mix(in srgb, var(--surface-panel) 80%, transparent);
    border: 1px solid var(--primary-color);
    border-radius: 3px;
    color: var(--text-light);
    font-size: 0.75em;
    text-align: center;
}

.initiative-input-overlay input:focus {
    outline: none;
    border-color: var(--accent-color);
    box-shadow: 0 0 6px color-mix(in srgb, var(--accent-color) 40%, transparent);
}

.initiative-input-overlay button {
    padding: 4px 8px;
    font-size: 0.7em;
    min-width: 28px;
}

.combat-initiative-input-wrapper {
    display: flex;
    flex-direction: row;
    gap: 2px;
    align-items: center;
    position: relative;
}

.combat-stat-group-header > .combat-initiative-input-wrapper {
    flex-direction: row;
    justify-content: center;
}

.combat-initiative-input-group {
    display: flex;
    gap: 2px;
    align-items: center;
}

.manual-initiative-input {
    width: 32px;
    padding: 1px 3px;
    background: color-mix(in srgb, var(--surface-panel) 50%, transparent);
    border: 1px solid var(--primary-color);
    border-radius: 2px;
    color: var(--text-light);
    font-size: 0.65em;
    text-align: center;
}

.manual-initiative-input:focus {
    outline: none;
    border-color: var(--accent-color);
}

.combat-initiative-modifier {
    color: var(--text-light);
    font-size: 0.55em;
    opacity: 0.6;
}

/* ============================================================================
   CARD BODY - Image + Stats Side-by-Side (TCG Style)
   ============================================================================ */

.combat-card-body {
    display: flex;
    gap: 4px;
    padding: 4px;
    flex: 1;
    min-height: 0;
}

/* Image Section - Left or Top */
.combat-card-image-section {
    flex: 0 0 90px;
    min-width: 90px;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.combat-image-container {
    width: 100%;
    height: 120px;
    overflow: hidden;
    border-radius: 3px;
    background: color-mix(in srgb, var(--surface-panel) 85%, transparent 15%);
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid var(--border-color, rgba(255, 255, 255, 0.1));
    position: relative;
}

.combat-image-container img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

.combat-image-placeholder,
.combat-image-placeholder,
.combat-image-error {
    color: var(--text-light);
    opacity: 0.5;
    font-size: 0.6em;
    text-align: center;
    padding: 4px;
}

/* Stats Section - Right of Image */
.combat-card-stats-section {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
}

.combat-stat-group {
    display: flex;
    align-items: center;
    gap: 3px;
}

.combat-stat-group.flex-1 {
    flex: 1;
}

.combat-stat-label {
    color: var(--text-light);
    font-size: 0.6em;
    font-weight: 600;
}

.combat-stat-value {
    font-size: 0.7em;
    font-weight: 600;
}

.combat-stat-value.ac {
    font-size: 0.75em;
    font-weight: 700;
}

.combat-stat-value.hd {
    font-size: 0.65em;
    color: var(--text-light);
}

/* HP Color Variants */

.combat-hp-bar-container {
    background: color-mix(in srgb, var(--surface-panel) 30%, transparent);
    border-radius: 2px;
    height: 3px;
    overflow: hidden;
    margin-top: 2px;
}

.combat-hp-bar {
    height: 100%;
    transition: width 0.3s;
}

.combat-hp-bar[data-hp-color="healthy"] { background: var(--secondary-color); }
.combat-hp-bar[data-hp-color="warning"] { background: var(--warning-color, #ff8844); }
.combat-hp-bar[data-hp-color="critical"] { background: var(--danger-color, #ff4444); }
.combat-hp-bar[data-hp-color="dead"] { background: #666; }

/* HP Bar Overlay on Image */
.combat-hp-bar-overlay {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 6px;
    background: color-mix(in srgb, rgba(0, 0, 0, 0.6) 70%, transparent);
    border-radius: 0 0 3px 3px;
    overflow: hidden;
    z-index: 10;
}

.combat-hp-bar-overlay .combat-hp-bar {
    height: 100%;
    border-radius: 0;
}

.combat-section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 2px;
}

.combat-section-title {
    color: var(--text-light);
    font-size: 0.6em;
    font-weight: 600;
}

/* Conditions - Compact Badges */
.combat-section-panel {
    padding: 3px 4px;
    background: color-mix(in srgb, var(--surface-panel) 85%, transparent 15%);
    border-radius: 3px;
    border-left: 2px solid var(--accent-color);
}

.combat-conditions-list {
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
}

.combat-condition-badge {
    display: flex;
    align-items: center;
    gap: 2px;
    padding: 1px 3px;
    background: color-mix(in srgb, var(--primary-color) 20%, transparent);
    border: 1px solid var(--primary-color);
    border-radius: 2px;
    font-size: 0.6em;
}

.combat-condition-name {
    color: var(--text-light);
}

.combat-condition-duration {
    color: var(--accent-color);
    font-weight: 600;
}

.remove-condition-btn {
    margin-left: 1px;
    background: transparent;
    border: none;
    color: var(--text-light);
    cursor: pointer;
    opacity: 0.6;
    font-size: 0.7em;
    padding: 0 1px;
    transition: opacity 0.2s ease;
}

.remove-condition-btn:hover {
    opacity: 1;
}

.combat-conditions-header {
    margin-bottom: 2px;
}

.combat-conditions-header.no-conditions {
    margin-bottom: 0;
}

.add-condition-btn {
    padding: 1px 4px;
    font-size: 0.6em;
}

/* ============================================================================
   CARD FOOTER - Actions at Bottom (Like MTG Rules Text/Footer)
   ============================================================================ */

.combat-card-footer {
    border-top: 2px solid var(--primary-color);
    padding: 3px 4px;
    background: color-mix(in srgb, var(--primary-color) 10%, transparent);
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.combat-actions-row {
    display: flex;
    gap: 3px;
}

.leave-combat-btn,
.view-spells-btn,
.leave-combat-btn,
.view-spells-btn,
.open-dice-tray-btn {
    flex: 1;
    padding: 3px 6px;
    font-size: 0.65em;
}

.advantage-btn,
.advantage-btn,
.disadvantage-btn {
    flex: 0 0 auto;
    padding: 3px 8px;
    font-size: 0.65em;
    font-weight: 600;
    min-width: 36px;
    transition: all 0.2s ease;
}

.advantage-btn,
.advantage-btn,
.disadvantage-btn {
    background: color-mix(in srgb, var(--accent-color) 30%, transparent);
    border: 1px solid var(--accent-color);
    color: var(--text-light);
}

.advantage-btn:hover,
.advantage-btn:hover,
.disadvantage-btn:hover {
    background: color-mix(in srgb, var(--accent-color) 50%, transparent);
    border-color: var(--accent-color);
    box-shadow: 0 0 6px color-mix(in srgb, var(--accent-color) 40%, transparent);
    color: var(--text-light);
}

.advantage-btn.active,
.advantage-btn.active,
.disadvantage-btn.active {
    background: color-mix(in srgb, var(--accent-color) 60%, transparent);
    border: 2px solid var(--accent-color);
    color: var(--text-light);
    box-shadow: 0 0 10px color-mix(in srgb, var(--accent-color) 50%, transparent);
    font-weight: 700;
}

/* Manual-roll mode toggle — match Adv/Dis sizing, but use a distinct green
   "on" state so it's obvious whether physical-dice entry is enabled. */
.manual-roll-btn {
    flex: 0 0 auto;
    padding: 3px 8px;
    font-size: 0.65em;
    font-weight: 600;
    min-width: 44px;
    transition: all 0.2s ease;
    background: transparent;
    border: 1px dashed color-mix(in srgb, var(--text-light) 45%, transparent);
    color: color-mix(in srgb, var(--text-light) 70%, transparent);
}

.manual-roll-btn:hover {
    border-color: #43c86a;
    color: var(--text-light);
    box-shadow: 0 0 6px color-mix(in srgb, #43c86a 40%, transparent);
}

.manual-roll-btn.active {
    background: color-mix(in srgb, #43c86a 65%, transparent);
    border: 2px solid #43c86a;
    color: #fff;
    box-shadow: 0 0 10px color-mix(in srgb, #43c86a 55%, transparent);
    font-weight: 700;
}

/* Little state dot so on/off is legible even at a glance */
.manual-roll-btn::before {
    content: "○ ";
    opacity: 0.8;
}
.manual-roll-btn.active::before {
    content: "● ";
}

.view-spells-btn-full {
    width: 100%;
    padding: 4px 6px;
    background: color-mix(in srgb, var(--primary-color) 30%, transparent);
    border: 1px solid var(--primary-color);
    border-radius: 3px;
    color: var(--primary-color);
    cursor: pointer;
    font-size: 0.65em;
    font-weight: 600;
    text-align: center;
}

/* Collapsible Sections - Compact */
.combat-collapsible-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 2px 4px;
    background: color-mix(in srgb, var(--surface-panel) 85%, transparent 15%);
    border-radius: 3px;
    cursor: pointer;
    border-left: 2px solid var(--accent-color);
    margin-top: 2px;
}

.combat-collapsible-header.image {
    border-left-color: var(--primary-color);
}

.combat-collapsible-content {
    padding: 2px 0;
}

.combat-collapsible-content.hidden {
    display: none;
}

.combat-collapsible-content.visible {
    display: block;
}

.combat-collapsible-icon {
    font-size: 0.75em;
    font-weight: 700;
    width: 14px;
    text-align: center;
    color: var(--accent-color);
}

.combat-collapsible-header.image .combat-collapsible-icon {
    color: var(--primary-color);
}

/* Features/Items Sections */
.features-section,

.features-list {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.features-empty {
    color: var(--text-light);
    opacity: 0.6;
    font-size: 0.6em;
    padding: 3px;
    text-align: center;
}

/* Items Grid */
.combat-items-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 2px;
}

.combat-item-card {
    display: flex;
    flex-direction: column;
    padding: 2px 4px;
    background: color-mix(in srgb, var(--accent-color) 15%, transparent);
    border: 1px solid var(--accent-color);
    border-radius: 2px;
    min-width: 0;
    font-size: 0.6em;
}

.combat-item-name {
    color: var(--accent-color);
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin-bottom: 1px;
}

.combat-item-damage {
    color: var(--text-light);
    opacity: 0.7;
    margin-bottom: 1px;
}

.combat-item-roll-btn {
    padding: 1px 4px;
    background: color-mix(in srgb, var(--accent-color) 30%, transparent);
    border: 1px solid var(--accent-color);
    border-radius: 2px;
    color: var(--accent-color);
    cursor: pointer;
    font-size: 0.6em;
    font-weight: 600;
    width: 100%;
    display: block;
}

.spells-button-container {
    margin-top: 2px;
}

/* ============================================================================
   LAYOUT - Combat Tracker Container
   ============================================================================ */

.combat-split-view {
    display: flex;
    flex-direction: column;
    height: calc(100vh - 60px);
    gap: 8px;
    padding: 8px;
    overflow-y: auto;
}

.combat-tracker-panel {
    flex: 0 0 auto;
    min-height: 200px;
    max-height: 50vh;
    overflow: hidden;
    background: color-mix(in srgb, var(--surface-panel) 85%, transparent 15%);
    border-radius: 4px;
    border: 1px solid var(--primary-color);
    display: flex;
    flex-direction: column;
}

.combat-carousel-container {
    flex: 1;
    overflow-x: auto;
    overflow-y: auto;
    padding: 12px;
    scroll-behavior: smooth;
    scrollbar-width: thin;
    scrollbar-color: var(--primary-color) color-mix(in srgb, var(--surface-panel) 85%, transparent 15%);
    min-height: 0;
}

.combat-carousel-container::-webkit-scrollbar {
    height: 8px;
}

.combat-carousel-container::-webkit-scrollbar-track {
    background: color-mix(in srgb, var(--theme-color-2, var(--abyssal-dark)) 30%, transparent);
}

.combat-carousel-container::-webkit-scrollbar-thumb {
    background: var(--primary-color, var(--abyssal-glow));
    border-radius: 4px;
}

.combat-carousel {
    display: flex;
    gap: 12px;
    align-items: flex-start;
    min-width: max-content;
}

.battle-map-panel {
    flex: 1;
    min-height: 300px;
    display: flex;
    flex-direction: column;
    background: color-mix(in srgb, var(--surface-panel) 85%, transparent 15%);
    border-radius: 4px;
    border: 1px solid var(--primary-color);
    overflow: hidden;
}

.battle-map-header {
    padding: 8px 12px;
    border-bottom: 1px solid var(--abyssal-glow);
    display: flex;
    justify-content: space-between;
    align-items: center;
    background: color-mix(in srgb, var(--surface-panel) 90%, transparent 10%);
}

.battle-map-header-left {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.battle-map-title {
    color: var(--primary-color);
    font-size: 0.9em;
    font-weight: 600;
}

.battle-map-select {
    padding: 4px 8px;
    background: color-mix(in srgb, var(--surface-panel) 50%, transparent);
    border: 1px solid var(--primary-color);
    border-radius: 3px;
    color: var(--text-light);
    font-size: 0.75em;
}

.battle-map-select:focus {
    outline: none;
    border-color: var(--accent-color);
}

.battle-map-name-display {
    padding: 4px 8px;
    color: var(--text-light);
    font-size: 0.75em;
    font-weight: 500;
    opacity: 0.9;
}

.battle-map-controls {
    display: flex;
    gap: 6px;
    align-items: center;
}

/* GM switch: do player moves apply at once, or wait here for approval. */
.battle-map-toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-right: 4px;
    color: var(--abyssal-light, #cfe3ee);
    font-size: 0.8em;
    white-space: nowrap;
    cursor: pointer;
}

.battle-map-toggle input {
    cursor: pointer;
}

/* ⚠️ `hidden` loses to any author rule that sets `display`, and the rule
   above is one — so `wrap.hidden = true` did nothing and the GM's approval
   switch sat on a player's screen. The code asking for it to be hidden was
   right; this stylesheet was overruling it. */
.battle-map-toggle[hidden] {
    display: none;
}

/* Moves waiting on the GM, shown with the map they affect. */
.battle-map-approvals {
    border-top: 1px solid var(--abyssal-glow, #2a6f80);
    padding: 8px 12px;
    background: rgba(10, 16, 34, 0.55);
}

.battle-map-approvals-title {
    color: var(--abyssal-glow, #7fd4e6);
    font-size: 0.8em;
    font-weight: 600;
    margin-bottom: 6px;
}

.battle-map-approvals-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.battle-map-approval-row {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 0.85em;
    color: var(--abyssal-light, #cfe3ee);
}

.battle-map-approval-row span {
    flex: 1;
}

.image-scale-control {
    display: none;
    align-items: center;
    gap: 6px;
}

.image-scale-control.visible {
    display: flex;
}

.image-scale-label {
    color: var(--text-light);
    font-size: 0.7em;
}

.image-scale-slider {
    width: 100px;
}

.image-scale-value {
    color: var(--primary-color);
    font-size: 0.7em;
    min-width: 40px;
    text-align: right;
}

.battle-map-canvas-container {
    flex: 1;
    position: relative;
    overflow: hidden;
    background: var(--bg-dark, var(--theme-color-2, #0a0e1f));
}

#battle-map-canvas {
    display: block;
    width: 100%;
    height: 100%;
    cursor: default;
}

.toggle-map-btn {
    padding: 4px 8px;
    font-size: 0.7em;
}

/* ============================================================================
   NAVIGATION
   ============================================================================ */

.combat-top-nav-bar {
    padding: 8px 16px;
}

.combat-top-nav-title {
    font-size: 1em;
}

.combat-top-nav-icon {
    width: 20px;
    height: 20px;
}

.combat-top-nav-actions {
    gap: 6px;
}

.combat-round-display-wrapper {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-right: 12px;
}

.combat-round-label {
    color: var(--text-light);
    font-size: 0.75em;
    font-weight: 600;
}

.combat-round-value {
    color: var(--primary-color);
    font-size: 0.9em;
    font-weight: 700;
    min-width: 20px;
    text-align: center;
}

.combat-nav-btn {
    padding: 4px 8px;
    font-size: 0.7em;
}

.combat-nav-btn-primary {
    background: var(--primary-color);
}

/* ============================================================================
   MODALS - Simplified
   ============================================================================ */

.combat-modal-overlay {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: rgba(0, 0, 0, 0.8);
    z-index: 10001;
    align-items: center;
    justify-content: center;
}

.combat-modal-overlay.show {
    display: flex;
}

.combat-modal-content {
    background: color-mix(in srgb, var(--surface-panel) 95%, transparent);
    border: 1px solid var(--primary-color);
    border-radius: 4px;
    padding: 12px;
    max-width: 700px;
    width: 90%;
    max-height: 80vh;
    box-shadow: 0 0 20px color-mix(in srgb, var(--primary-color) 40%, transparent);
    display: flex;
    flex-direction: column;
}

.combat-modal-content-large {
    padding: 24px;
    border: 2px solid var(--primary-color);
    border-radius: 8px;
    max-width: 600px;
}

.combat-modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 12px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--primary-color);
}

.combat-modal-header-large {
    margin-bottom: 20px;
    padding-bottom: 12px;
    border-bottom: 2px solid var(--primary-color);
}

.combat-modal-title {
    color: var(--primary-color);
    margin: 0;
    font-size: 0.9em;
    font-weight: 600;
}

.combat-modal-title-large {
    font-size: 1.3em;
}

.combat-modal-close {
    background: transparent;
    border: none;
    color: var(--text-light);
    font-size: 1.2em;
    cursor: pointer;
    padding: 0;
    width: 20px;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: color 0.2s ease;
}

.combat-modal-close:hover {
    color: var(--accent-color);
}

.combat-modal-close-large {
    font-size: 1.5em;
    width: 30px;
    height: 30px;
}

/* ============================================================================
   DEFEATED ENEMIES SECTION
   ============================================================================ */

.defeated-enemies-section {
    flex: 0 0 auto;
    min-height: 80px;
    max-height: 200px;
    background: color-mix(in srgb, var(--surface-panel) 90%, transparent 10%);
    border-top: 1px solid var(--primary-color);
    padding: 12px;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    flex-shrink: 0;
}

.defeated-enemies-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 8px;
    padding-bottom: 6px;
    border-bottom: 1px solid var(--primary-color);
}

.defeated-enemies-title {
    color: var(--primary-color);
    font-size: 0.85em;
    font-weight: 600;
    margin: 0;
}

.defeated-enemies-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.defeated-enemy-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 8px 10px;
    background: color-mix(in srgb, var(--surface-panel) 85%, transparent 15%);
    border: 1px solid var(--primary-color);
    border-radius: 4px;
    gap: 12px;
}

.defeated-enemy-info {
    flex: 1;
    min-width: 0;
}

.defeated-enemy-name {
    color: var(--primary-color);
    font-size: 0.85em;
    font-weight: 600;
    margin-bottom: 2px;
}

.defeated-enemy-details {
    color: var(--text-light);
    font-size: 0.7em;
    opacity: 0.8;
}

.defeated-enemy-actions {
    display: flex;
    gap: 6px;
    flex-shrink: 0;
}

.approve-enemy-btn,
.approve-enemy-btn,
.reject-enemy-btn {
    padding: 4px 8px;
    font-size: 0.7em;
    white-space: nowrap;
}

.combat-modal-body {
    flex: 1;
    overflow-y: auto;
    min-height: 0;
}

.combat-modal-footer {
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--primary-color);
}

.combat-modal-footer-large {
    margin-top: 20px;
    padding-top: 16px;
    border-top: 2px solid var(--primary-color);
    display: flex;
    gap: 12px;
}

.combat-modal-input {
    flex: 1;
    padding: 8px;
    background: color-mix(in srgb, var(--surface-panel) 50%, transparent);
    border: 1px solid var(--primary-color);
    border-radius: 4px;
    color: var(--text-light);
    font-size: 0.9em;
}

.combat-modal-input:focus {
    outline: none;
    border-color: var(--accent-color);
}

.combat-modal-button-primary {
    padding: 8px 16px;
    background: rgba(168, 85, 247, 0.3);
    border: 2px solid var(--abyssal-glow);
    border-radius: 4px;
    color: var(--abyssal-glow);
    cursor: pointer;
    font-size: 0.9em;
    font-weight: 600;
    transition: all 0.2s ease;
    margin-right: 8px;
}

.combat-modal-button-primary:hover {
    background: rgba(168, 85, 247, 0.5);
    border-color: var(--abyssal-teal);
    transform: scale(1.02);
}

.combat-modal-button-full {
    width: 100%;
    padding: 8px;
    background: color-mix(in srgb, var(--surface-panel) 40%, transparent);
    border: 1px solid var(--primary-color);
    border-radius: 3px;
    color: var(--text-light);
    cursor: pointer;
    font-size: 0.8em;
    font-weight: 600;
    transition: all 0.2s ease;
}

.combat-modal-button-full:hover {
    background: color-mix(in srgb, var(--surface-panel) 60%, transparent);
    border-color: var(--accent-color);
}

.combat-condition-button,
.combat-condition-button,
.combat-spell-button {
    padding: 8px 12px;
    background: color-mix(in srgb, var(--surface-panel) 30%, transparent);
    border: 1px solid var(--primary-color);
    border-radius: 6px;
    color: var(--text-light);
    cursor: pointer;
    font-size: 0.75em;
    text-align: left;
    transition: all 0.2s ease;
    display: flex;
    align-items: center;
    gap: 8px;
}

.combat-condition-button:hover,
.combat-condition-button:hover,
.combat-spell-button:hover {
    background: color-mix(in srgb, var(--secondary-color) 20%, transparent);
    border-color: var(--secondary-color);
    transform: scale(1.02);
}

.combat-condition-button-icon {
    font-size: 1.5em;
    flex-shrink: 0;
}

.combat-condition-button-content {
    flex: 1;
    min-width: 0;
}

.combat-condition-button-name {
    color: var(--primary-color);
    font-weight: 600;
    font-size: 1em;
    margin-bottom: 4px;
}

.combat-condition-button-description {
    color: var(--text-light);
    font-size: 0.85em;
    opacity: 0.8;
    line-height: 1.4;
}

.combat-spell-button-name {
    color: var(--primary-color);
    font-weight: 600;
    font-size: 0.9em;
    margin-bottom: 4px;
}

.combat-spell-button-meta {
    color: var(--text-light);
    font-size: 0.75em;
    opacity: 0.7;
    margin-bottom: 4px;
}

.combat-spell-button-description {
    color: var(--text-light);
    font-size: 0.7em;
    opacity: 0.8;
    line-height: 1.3;
    margin-bottom: 4px;
}

.combat-spell-button-details {
    color: var(--text-light);
    font-size: 0.7em;
    opacity: 0.6;
    margin-bottom: 4px;
}

.spells-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 8px;
}

/* Condition Icon Grid - Simplified */
.condition-icon-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(60px, 1fr));
    gap: 8px;
    padding: 8px;
}

.condition-icon-button {
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 1;
    background: color-mix(in srgb, var(--surface-panel) 85%, transparent 15%);
    border: 2px solid var(--primary-color);
    border-radius: 6px;
    cursor: pointer;
    transition: all 0.2s ease;
    padding: 8px;
}

.condition-icon-button:hover {
    background: color-mix(in srgb, var(--primary-color) 30%, transparent);
    border-color: var(--accent-color);
    transform: scale(1.1);
    box-shadow: 0 4px 12px color-mix(in srgb, var(--primary-color) 40%, transparent);
}

.condition-icon {
    font-size: 2em;
    line-height: 1;
}

/* ============================================================================
   UTILITIES
   ============================================================================ */

.combat-empty-state {
    text-align: center;
    padding: 40px;
    color: var(--text-light);
    opacity: 0.6;
}

.combat-empty-state-title {
    font-size: 1.2em;
    margin-bottom: 10px;
}

.combat-empty-state-message {
    font-size: 0.9em;
}

.rage-indicator {
    color: var(--danger-color, #ff4444);
    font-size: 0.7em;
    font-weight: 700;
    text-shadow: 0 0 4px color-mix(in srgb, var(--danger-color, #ff4444) 80%, transparent);
}

/* Remove old image section class - use new structure */
.image-section {
    display: none; /* Hide old collapsible image - using inline image now */
}

/* ============================================================================
   VIEWER ROLE - Hide buttons for characters viewers don't own
   ============================================================================ */

body.viewer-role .viewer-no-edit {
    display: none !important;
}

body.viewer-role .combat-initiative-value.viewer-no-edit,
body.viewer-role .combat-initiative-value.viewer-no-edit,
body.viewer-role .combat-initiative-label.viewer-no-edit {
    display: inline !important;
    visibility: visible !important;
}

body.dice-tray-page .open-dice-tray-btn {
    display: none !important;
}

body.viewer-role .roll-initiative-btn:not(.viewer-no-edit),
body.viewer-role .advantage-btn:not(.viewer-no-edit),
body.viewer-role .disadvantage-btn:not(.viewer-no-edit),
body.viewer-role .leave-combat-btn:not(.viewer-no-edit),
body.viewer-role .view-spells-btn:not(.viewer-no-edit),
body.viewer-role .roll-initiative-btn:not(.viewer-no-edit),
body.viewer-role .advantage-btn:not(.viewer-no-edit),
body.viewer-role .disadvantage-btn:not(.viewer-no-edit),
body.viewer-role .leave-combat-btn:not(.viewer-no-edit),
body.viewer-role .view-spells-btn:not(.viewer-no-edit),
body.viewer-role .cast-spell-modal-btn:not(.viewer-no-edit) {
    display: inline-block !important;
    visibility: visible !important;
}

/* Item roll buttons use block display (width: 100%) */
/* Roll buttons should always show if the item card is visible (they go together) */
.combat-item-roll-btn {
    display: block !important;
}

/* Hide roll buttons only if they have viewer-no-edit class AND user is a viewer */
body.viewer-role .combat-item-roll-btn.viewer-no-edit {
    display: none !important;
}

/* Hide top nav management buttons for viewers */
body.viewer-role #advance-round-btn.viewer-no-edit,
body.viewer-role #roll-all-npc-init-btn.viewer-no-edit,
body.viewer-role #long-rest-all-btn.viewer-no-edit,
body.viewer-role #advance-round-btn.viewer-no-edit,
body.viewer-role #roll-all-npc-init-btn.viewer-no-edit,
body.viewer-role #long-rest-all-btn.viewer-no-edit,
body.viewer-role #clear-combat-btn.viewer-no-edit {
    display: none !important;
}

/* Items Modal Styles */
.items-modal-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 8px;
}

.item-option-modal {
    background: rgba(27, 42, 106, 0.3);
    border: 2px solid var(--abyssal-glow);
    border-radius: 4px;
    padding: 10px;
    cursor: pointer;
    transition: all 0.2s;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.item-option-modal:hover {
    background: rgba(20, 184, 166, 0.2);
    border-color: var(--abyssal-teal);
    transform: scale(1.02);
}

.item-option-name {
    color: var(--abyssal-glow);
    font-weight: 600;
    font-size: 0.9em;
    margin-bottom: 4px;
}

.item-option-damage {
    color: var(--abyssal-light);
    font-size: 0.75em;
    opacity: 0.7;
    margin-bottom: 4px;
}

.combat-modal-empty {
    text-align: center;
    padding: 40px;
    color: var(--abyssal-light);
    opacity: 0.6;
}

/* Items modal roll button styling */
.items-modal-grid .combat-item-roll-btn {
    width: 100%;
    padding: 6px;
    background: rgba(168, 85, 247, 0.4);
    border: 1px solid var(--abyssal-glow);
    border-radius: 3px;
    color: var(--abyssal-glow);
    cursor: pointer;
    font-size: 0.75em;
    font-weight: 600;
    margin-top: auto;
}

/**
 * The features window.
 *
 * Features moved off the card because most of a creature's are passive, and a
 * collapsible section on every combatant was card space for reference text
 * nobody acts on. What is left on the card is a button carrying the only
 * number that matters mid-fight: how many can still be spent.
 */

.feature-window-group {
    margin: 10px 0 4px;
    font-size: 0.75em;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-dim);
}

.feature-window-group:first-child {
    margin-top: 0;
}

.feature-window-row {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    padding: 8px 10px;
    margin-bottom: 6px;
    border: 1px solid var(--border-color);
    border-radius: 6px;
}

/* On, and therefore doing something right now. */
.feature-window-row.is-active {
    border-color: var(--primary-color);
}

/* Reading, not acting — dimmer so the spendable ones read first. */
.feature-window-row.is-passive {
    opacity: 0.75;
}

.feature-window-main {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.feature-window-name {
    color: var(--primary-color);
    font-weight: 600;
    font-size: 0.95em;
}

.feature-window-uses {
    color: var(--text-light);
    font-size: 0.8em;
}

.feature-window-armour {
    color: var(--secondary-color, var(--abyssal-teal));
    font-size: 0.75em;
}

.feature-window-text {
    color: var(--text-light);
    opacity: 0.85;
    font-size: 0.8em;
    line-height: 1.4;
}

/*
 * On or off, as a button that lights up.
 *
 * A sliding switch was the first attempt and it was the wrong shape twice
 * over: the checkbox behind it was invisible under a stylesheet rule left
 * from the on-card version, and a switch reads as a setting you configure
 * rather than a thing you do in the moment. Lit means the feature is on.
 */
.feature-window-toggle {
    flex-shrink: 0;
    min-width: 46px;
    padding: 4px 10px;
    font-size: 0.8em;
    font-weight: 600;
    color: var(--text-dim);
    background: transparent;
    border: 1px solid var(--border-color);
    border-radius: 4px;
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.feature-window-toggle:hover {
    border-color: var(--primary-color);
    color: var(--text-light);
}

.feature-window-toggle[aria-pressed="true"] {
    color: var(--bg-dark);
    background: var(--primary-color);
    border-color: var(--primary-color);
    box-shadow: 0 0 8px color-mix(in srgb, var(--primary-color) 55%, transparent);
}

/* An action a creature is holding up reads the same as a feature that is on. */
.item-option-modal.is-active {
    border-color: var(--primary-color);
    background: color-mix(in srgb, var(--primary-color) 12%, transparent);
}

/* A reader watches the fight; they do not spend the monster's rage. */
.feature-window-toggle.viewer-no-edit {
    display: none;
}

/*
 * Which way armour moved.
 *
 * The card already showed "18/16" when AC was off its base, but both
 * directions took the same colour — a feature raising your armour and a
 * condition eating it looked identical.
 *
 * Both are fixed rather than themed, for the same reason the HP states are:
 * armour going up has to read as good and down as bad in every palette, and
 * these sit in the same family as critical #ff4444 and warning #ff8844.
 *
 * ⚠️ Raised cannot simply take --primary-color: that is what the number
 * already is at base, so it would indicate nothing.
 */
.combat-initiative-value[data-ac-direction="raised"] {
    color: #44dd88;
}

.combat-initiative-value[data-ac-direction="lowered"] {
    color: #ff8844;
}

/*
 * Spell slots, at the top of the window you cast from.
 *
 * They used to be a panel on every card. In a party where most combatants
 * cast nothing that is an empty row on every one of them, and for a caster it
 * duplicated what the window is for. The card keeps the count on its button.
 */
.spell-slots-strip {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    margin-bottom: 10px;
}

.spell-slots-label {
    font-size: 0.75em;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--text-dim);
}

.spell-slot-pip {
    padding: 1px 8px;
    border: 1px solid var(--border-color);
    border-radius: 10px;
    font-size: 0.8em;
    color: var(--primary-color);
}

/* Spent, and therefore not an option this turn. */
.spell-slot-pip.is-spent {
    color: var(--text-dim);
    opacity: 0.6;
}

/*
 * The six saves, on the card.
 *
 * This is the space the stats panel left when HP, AC and initiative moved to
 * the header, and it stayed empty for a long time. Features and spell slots
 * later moved into windows, and what a GM reaches for between those moments
 * — "everyone make a Dexterity save" — was only ever on the sheet.
 */
.combat-saves-panel {
    margin-bottom: 4px;
}

.combat-saves-row {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 3px;
}

.combat-save-pip {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 4px;
    padding: 2px 6px;
    background: transparent;
    border: 1px solid var(--border-color);
    border-radius: 3px;
    color: var(--text-light);
    cursor: pointer;
    font-size: 0.7em;
    line-height: 1.3;
}

.combat-save-pip:hover {
    border-color: var(--primary-color);
}

/*
 * Proficient in this one. Marked because it is the difference between the
 * number being right and being four-of-six too high, which is the bug
 * SavingThrowManager exists to stop.
 */
.combat-save-pip.is-proficient {
    border-color: var(--primary-color);
}

.combat-save-pip.is-proficient .combat-save-value {
    color: var(--primary-color);
    font-weight: 600;
}

.combat-save-name {
    opacity: 0.7;
    letter-spacing: 0.03em;
}

/*
 * A viewer watches; they do not roll the monster's saves.
 *
 * ⚠️ Dimmed, not gone. This rule had no !important, so the blanket
 * `body.viewer-role .viewer-no-edit { display: none !important }` beat it and
 * a player saw no saving throws at all on any card but their own — the six
 * numbers a GM asks the table for.
 */
body.viewer-role .combat-save-pip.viewer-no-edit {
    display: flex !important;
    cursor: default;
    opacity: 0.6;
    pointer-events: none;
}

/* ============================================================================
   TCG CARD — the tracker's card (S-38 FR-11–FR-16)

   ⚠️ Every rule from here down is qualified by .ct-tcg, the root on the
   tracker page's carousel container. This sheet ships inside the `all`
   bundle, so every page in the app loads it, and the dice tray draws the very
   same card markup through CombatTrackerUI. A bare .item-card or
   .combat-card-* rule here would restyle both. The settings preview opts in
   by wearing .ct-tcg itself.

   The card is layered, never one stretched picture:
     frame  — CSS border and inset hairline on .item-card
     art    — a separate image in the art window, painted by ::before behind
              the portrait (--ct-art-image), so any art drops in
     body   — opaque themed CSS surfaces under every number and control

   The markup is the existing card's. The grid below reorders it; no element,
   class, id or data attribute that a handler reads was changed.
   ============================================================================ */

.ct-tcg {
    /* The bundled placeholder. Replacing the art is a file swap; a campaign's
       own image arrives by overriding the property on this element. */
    --ct-art-default: url("/images/combat-card-art/default.webp");
    --ct-art-image: var(--ct-art-default);
    --ct-art-x: 50%;
    --ct-art-y: 50%;
    --ct-card-width: 300px;
    /* What the window falls back to when there is no image to size it, and
       the most any image may take. */
    --ct-portrait-min: 110px;
    --ct-portrait-max: 150px;

    /* Frame and body, from the theme (S-76 FR-6.1): a silver drawn from the
       theme's own text colour, and opaque panels from its surfaces. */
    --ct-frame: color-mix(in srgb, var(--text-light) 55%, var(--surface-base));
    --ct-frame-soft: color-mix(in srgb, var(--text-light) 20%, transparent);
    --ct-body: var(--surface-base);
    --ct-panel: color-mix(in srgb, var(--surface-panel) 45%, var(--surface-base));
    --ct-label: var(--text-dim);
    --ct-name-font: Georgia, "Times New Roman", serif;
}

/* Comfortable: the full-art density. Compact, the default, keeps the art to a
   banner so the stats stay in reach inside the 50vh roster. */
.ct-tcg[data-density="comfortable"] {
    --ct-card-width: 340px;
    /* Height comes from the 3:4 window below, not from this. */
    --ct-portrait-height: auto;
}

/*
 * ⚠️ The image sizes its own window, so there is no space around it.
 *
 * Every fixed shape was wrong for something: landscape windows cropped
 * portraits, and a 3:4 window letterboxed the square and landscape art this
 * campaign actually uses — and made the card 760px tall to do it (owner,
 * 2026-09-20: "too much space around the character images its way to tall").
 *
 * With the window taking the image's own proportions there is no letterbox
 * and no crop, whatever shape the art is. The cap below is the one exception:
 * art taller than it is cropped rather than allowed to run away with the
 * card, which is the trade a roster of cards has to make somewhere.
 */
.ct-tcg[data-density="comfortable"] {
    --ct-portrait-max: 220px;
}

.ct-tcg .combat-carousel .item-card,
.ct-tcg.combat-card-preview .item-card {
    flex: 0 0 var(--ct-card-width);
    width: var(--ct-card-width);
    min-width: var(--ct-card-width);
    max-width: var(--ct-card-width);
    padding: 0;
    cursor: default;
}

/*
 * The layers, top to bottom: name → art window → HP/AC/Init → saves,
 * conditions and resources → roll modes.
 *
 * The header and body wrappers step aside (display: contents) so their
 * children become rows of one grid. They still exist, so the smart update's
 * header.outerHTML swap and every querySelector keep working.
 */
.ct-tcg .combat-card-wrapper {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    height: auto;
}

.ct-tcg .combat-card-header,
.ct-tcg .combat-card-body {
    display: contents;
}

.ct-tcg .combat-card-header-left { order: 1; }
.ct-tcg .combat-card-image-section { order: 2; }
.ct-tcg .combat-card-header-right { order: 3; }
.ct-tcg .combat-card-stats-section { order: 4; }
.ct-tcg .combat-card-footer { order: 5; }

/*
 * The portrait window — the creature's own image, and the biggest thing on
 * the card.
 *
 * ⚠️ The campaign's art is NOT in here. It is the card's background (below),
 * behind the whole card; this window holds the character or NPC image on top
 * of it. An earlier version had the art in this window *behind* the portrait,
 * which is not what the art is for and left the portrait a thumbnail.
 */
.ct-tcg .combat-card-image-section {
    display: block;
    flex: none;
    min-width: 0;
}

.ct-tcg .combat-image-container {
    height: auto;
    /* No image of its own: the card's art shows through this much of it. */
    min-height: var(--ct-portrait-min);
    max-height: var(--ct-portrait-max);
    border: 0;
    border-radius: 0;
    /* Transparent, so a creature with no image of its own shows the card's
       art through the window rather than an empty grey panel. */
    background: transparent;
    justify-content: center;
    isolation: isolate;
}

.ct-tcg .combat-image-container img {
    width: 100%;
    height: 100%;
    max-width: none;
    max-height: none;
    margin: 0;
    /* `cover` cropped every portrait: the window is landscape and character
       art is usually taller than it is wide, so filling it cut the picture
       off — a 1024×1024 portrait lost 36% off the bottom. Whatever `contain`
       does not fill, the card's own art shows through. */
    /* Width of the card, height from the picture: the window is the image's
       own shape, so nothing is letterboxed and nothing is cropped until the
       cap above. */
    height: auto;
    object-fit: cover;
    object-position: center center;
}

/* No portrait: the card's art fills the window, so "No Image" is said only to
   a screen reader rather than printed across the picture. */
.ct-tcg .combat-image-placeholder,
.ct-tcg .combat-image-error {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}

/* ----------------------------------------------------------------------------
   TCG card — finish (step 3)

   Card and control text is 12px or larger (FR-12), in px rather than em: the
   old card sized from 0.55em, and an em inherits whatever the page set.
   Numbers are tabular so a changing HP does not shuffle its neighbours.
   ---------------------------------------------------------------------------- */

.ct-tcg .combat-carousel .item-card,
.ct-tcg.combat-card-preview .item-card {
    padding: 4px;
    border: 2px solid var(--ct-frame);
    border-radius: 12px;
    /* The campaign's art, as the card's own background — behind the whole
       card, not inside the portrait window. Every panel over it is opaque,
       so no number is ever read against a picture. */
    background-color: var(--ct-body);
    /*
     * ⚠️ Two layers of the same art, because `cover` alone left the
     * top-to-bottom control with nothing to do: the bundled art is 720×411
     * and the card is about 300×508, so covering it scales the art to
     * 890×508 — the height matches exactly. 590px of the width hangs off the
     * sides, and not one pixel of height. Left-to-right moved; top-to-bottom
     * could not, whatever it was set to.
     *
     * The top layer is deliberately taller than the card, so both controls
     * have somewhere to move. The `cover` layer beneath it guarantees no gap
     * for art too narrow to fill the card at that height.
     */
    background-image: var(--ct-art-image), var(--ct-art-image);
    background-size: auto 125%, cover;
    background-position: var(--ct-art-x) var(--ct-art-y), center center;
    background-repeat: no-repeat, no-repeat;
    backdrop-filter: none;
    box-shadow: 0 6px 18px color-mix(in srgb, black 35%, transparent);
    color: var(--text-light);
    font-size: 13px;
    line-height: 1.3;
    font-variant-numeric: tabular-nums;
    transition: border-color 0.2s ease, outline-color 0.2s ease;
}

/* Cards hold still: no lift on hover, and (below) no scale-up for state. */
.ct-tcg .combat-carousel .item-card:hover,
.ct-tcg.combat-card-preview .item-card:hover {
    transform: none;
    box-shadow: 0 6px 18px color-mix(in srgb, black 35%, transparent);
}

/* The inner hairline of the frame. Transparent above the portrait so the art
   shows, and solid from the stats down so the numbers sit on a real surface. */
.ct-tcg .combat-card-wrapper {
    border: 1px solid var(--ct-frame-soft);
    border-radius: 8px;
    overflow: hidden;
    background: transparent;
}

/* Name bar — over the art, so it carries its own surface. */
.ct-tcg .combat-card-header-left {
    gap: 2px;
    padding: 7px 10px 6px;
    background: linear-gradient(180deg,
        color-mix(in srgb, var(--ct-body) 92%, transparent) 0%,
        color-mix(in srgb, var(--ct-body) 72%, transparent) 100%);
}

/* Everything below the portrait sits on the card's own surface. */
.ct-tcg .combat-card-header-right,
.ct-tcg .combat-card-stats-section {
    background: color-mix(in srgb, var(--ct-body) 88%, transparent);
}

.ct-tcg .combat-card-title-wrapper {
    font-family: var(--ct-name-font);
    font-size: 16px;
    font-weight: 700;
    line-height: 1.2;
    color: var(--text-light);
    /* Long names grow the card instead of being cut off (FR-12). */
    white-space: normal;
    overflow: visible;
    overflow-wrap: anywhere;
}

.ct-tcg .combat-card-meta {
    gap: 6px;
    font-size: 12px;
    color: var(--ct-label);
    opacity: 1;
}

/* Art window */
.ct-tcg .combat-image-container {
    border-block: 1px solid var(--ct-frame-soft);
}

.ct-tcg .combat-image-container img {
    border: 1px solid var(--ct-frame);
    border-radius: 6px;
    box-shadow: 0 2px 8px color-mix(in srgb, black 50%, transparent);
}

.ct-tcg[data-density="comfortable"] .combat-image-container img {
    border: 0;
    border-radius: 0;
    box-shadow: none;
    filter: drop-shadow(0 4px 10px color-mix(in srgb, black 55%, transparent));
}

.ct-tcg .combat-hp-bar-overlay {
    height: 5px;
    border-radius: 0;
    background: color-mix(in srgb, black 55%, transparent);
}

/* HP / AC / Init — the numbers a GM reads first */
.ct-tcg .combat-card-header-right {
    display: grid;
    grid-template-columns: 1.5fr 1fr 1fr;
    gap: 6px;
    margin: 0;
    padding: 8px 10px 6px;
}

.ct-tcg .combat-stat-group-header {
    justify-content: center;
    gap: 0;
    min-width: 0;
    padding: 3px 4px 4px;
    background: var(--ct-panel);
    border: 1px solid var(--ct-frame-soft);
    border-radius: 6px;
}

.ct-tcg .combat-initiative-label {
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ct-label);
    opacity: 1;
}

.ct-tcg .combat-initiative-value {
    font-size: 18px;
    line-height: 1.15;
    white-space: nowrap;
}

.ct-tcg .combat-initiative-value.editable-initiative.dash {
    font-size: 18px;
}

.ct-tcg .combat-initiative-modifier {
    font-size: 12px;
    color: var(--ct-label);
    opacity: 1;
}

.ct-tcg .combat-card-header-right .roll-initiative-btn {
    min-width: 26px;
    min-height: 24px;
    padding: 2px 4px;
    font-size: 13px;
}

/* Saves, conditions and resources */
.ct-tcg .combat-card-stats-section {
    gap: 8px;
    padding: 2px 10px 8px;
}

.ct-tcg .combat-section-header {
    margin-bottom: 4px !important; /* the markup sets its own inline */
}

.ct-tcg .combat-section-title {
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ct-label);
}

.ct-tcg .combat-saves-panel {
    margin: 0;
}

/* One row of six, name over value: two rows of three cost the roster a line. */
.ct-tcg .combat-saves-row {
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 3px;
}

.ct-tcg .combat-save-pip {
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0;
    min-height: 36px;
    padding: 3px 0;
    background: var(--ct-panel);
    border: 1px solid var(--ct-frame-soft);
    border-radius: 5px;
    font-size: 12px;
    line-height: 1.2;
}

.ct-tcg .combat-save-name {
    font-size: 12px;
    color: var(--ct-label);
    opacity: 1;
}

.ct-tcg .combat-save-value {
    font-size: 14px;
    font-weight: 600;
}

/* Proficiency is marked by more than colour: a heavier underline. */
.ct-tcg .combat-save-pip.is-proficient {
    border-color: var(--ct-frame-soft);
    border-bottom: 2px solid var(--primary-color);
}

.ct-tcg .combat-section-panel {
    padding: 6px 8px;
    background: var(--ct-panel);
    border: 1px solid var(--ct-frame-soft);
    border-radius: 6px;
}

/* ⚠️ The add/remove buttons carry inline font sizes (0.65em, 0.8em) from the
   shared renderer. Changing the markup would change the dice tray's cards, so
   the tracker overrides them here instead. */
.ct-tcg .add-condition-btn {
    min-width: 26px;
    min-height: 24px;
    padding: 0 8px !important;
    font-size: 14px !important;
}

.ct-tcg .combat-condition-badge {
    gap: 4px;
    padding: 2px 4px 2px 8px;
    background: color-mix(in srgb, var(--accent-color) 16%, var(--ct-body));
    border: 1px solid color-mix(in srgb, var(--accent-color) 55%, transparent);
    border-radius: 999px;
    font-size: 12px;
}

.ct-tcg .combat-condition-duration {
    font-size: 12px;
}

.ct-tcg .remove-condition-btn {
    min-width: 20px;
    padding: 0 4px !important;
    font-size: 15px !important;
    line-height: 1;
    opacity: 0.8 !important;
}

.ct-tcg .spells-button-container {
    display: flex;
    gap: 6px;
    margin: 0;
}

.ct-tcg .spells-button-container:empty {
    display: none;
}

.ct-tcg .spells-button-container .btn {
    flex: 1 1 0;
    min-height: 30px;
    padding: 4px 6px;
    font-size: 13px;
}

/* Roll modes and Leave */
.ct-tcg .combat-card-footer {
    gap: 0;
    padding: 7px 10px 8px;
    background: color-mix(in srgb, var(--surface-panel) 25%, var(--ct-body));
    border-top: 1px solid var(--ct-frame-soft);
}

.ct-tcg .combat-actions-row {
    display: grid;
    /* Manual carries its on/off dot, so it gets the widest column. */
    grid-template-columns: 1fr 1fr 1.4fr 1fr;
    gap: 5px;
}

.ct-tcg .combat-actions-row .btn {
    min-width: 0;
    min-height: 28px;
    padding: 3px 4px;
    font-size: 12px;
}

/* Buttons inside a card do not jump on hover either. */
.ct-tcg .item-card .btn:hover {
    transform: none;
}

/* The old state treatment scaled the card up with a heavy glow — a card that
   jumps and crowds its neighbours. State is shown without moving it. */
.ct-tcg .combat-carousel .item-card.current-turn,
.ct-tcg .combat-carousel .item-card.dice-tray-active {
    transform: none;
    z-index: auto;
    border-width: 2px;
    box-shadow: 0 6px 18px color-mix(in srgb, black 35%, transparent);
}

/* ----------------------------------------------------------------------------
   The roster's space budget

   The TCG card is taller than the old one (about 400px compact), and the
   roster was capped at 50vh — so a card's lower rows (conditions, resources,
   roll modes) sat behind a scroll *inside* the carousel, inside a page that
   scrolls too. Nested scrolling that hides controls is the thing to avoid.

   So the roster now sizes to its tallest card, up to 75vh; only a card taller
   than that (a great many conditions) scrolls inside. The map keeps its 300px
   minimum and the page scrolls as a whole when the window is shorter than
   both. An empty defeated-enemies list, which held 110px open to say there
   was nothing in it, folds to one line.
   ---------------------------------------------------------------------------- */

.combat-tracker-page .combat-tracker-panel {
    max-height: 75vh;
}

.combat-tracker-page .combat-tracker-panel:has(.ct-tcg) {
    overflow-y: auto;
}

/* Content height, horizontal scroll only. With overflow-y left on auto, the
   horizontal scrollbar's own height spilled into a second, vertical one. Past
   the 75vh cap it is the panel that scrolls, not the carousel. */
.combat-tracker-page .combat-carousel-container.ct-tcg {
    flex: 0 0 auto;
    overflow-y: hidden;
}

.combat-tracker-page .defeated-enemies-section:not(:has(.defeated-enemy-item)) {
    flex-direction: row;
    align-items: center;
    gap: 12px;
    min-height: 0;
    padding: 6px 12px;
}

.combat-tracker-page .defeated-enemies-section:not(:has(.defeated-enemy-item)) .defeated-enemies-header {
    order: 2;
    margin: 0 0 0 auto;
    padding: 0;
    border: 0;
}

.combat-tracker-page .defeated-enemies-section:not(:has(.defeated-enemy-item)) .defeated-enemies-title {
    display: none;
}

.combat-tracker-page .defeated-enemies-section:not(:has(.defeated-enemy-item)) .defeated-enemies-list > div {
    padding: 0 !important; /* the empty message carries inline padding */
    text-align: left !important;
}

.ct-tcg .initiative-input-overlay input,
.ct-tcg .initiative-input-overlay button {
    font-size: 13px;
}

/* ----------------------------------------------------------------------------
   Status, toolbar and icons (step 5, S-38 FR-15)
   ---------------------------------------------------------------------------- */

/*
 * Two different states, told apart without colour.
 *
 * Current turn and the active dice tray used to share one treatment — the
 * same thick border, the same glow, the same scale-up — so two different
 * facts looked identical, and a card that was both looked like a card that
 * was one. Now the turn is a solid edge with a label at the top left of the
 * art; the dice tray is an inset dashed outline with a label at the top
 * right. Both can show at once, and each says what it is in words.
 */
.ct-tcg .combat-card-image-section {
    position: relative;
}

.ct-tcg .item-card.current-turn .combat-card-image-section::before,
.ct-tcg .item-card.dice-tray-active .combat-card-image-section::after {
    position: absolute;
    top: 6px;
    z-index: 2;
    padding: 2px 7px;
    border-radius: 4px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.04em;
    line-height: 1.4;
    white-space: nowrap;
    pointer-events: none;
}

.ct-tcg .item-card.current-turn .combat-card-image-section::before {
    content: "Current turn";
    left: 6px;
    background: color-mix(in srgb, var(--primary-color) 88%, black);
    border: 1px solid var(--primary-color);
    color: var(--bg-dark);
}

.ct-tcg .item-card.dice-tray-active .combat-card-image-section::after {
    content: "Dice tray";
    right: 6px;
    background: color-mix(in srgb, black 72%, transparent);
    border: 1px dashed var(--secondary-color);
    color: var(--secondary-color);
}

.ct-tcg .combat-carousel .item-card.current-turn {
    border-color: var(--primary-color);
}

/* Inset, so it reads as a different mark from the frame itself. */
.ct-tcg .combat-carousel .item-card.dice-tray-active {
    outline: 2px dashed var(--secondary-color);
    outline-offset: -7px;
}

/* The name's "←" said the same thing as the label, in a way a reader has to
   work out. The label says it. */
.ct-tcg .combat-card-title-wrapper .current-turn-indicator {
    display: none;
}

.ct-tcg .rage-indicator {
    display: inline-flex;
    vertical-align: -2px;
    color: var(--danger-color, #ff4444);
}

/* Card button icons, from the app's sprite (the renderer's icons option). */
.ct-tcg .ct-btn-icon {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
}

.ct-tcg .rage-indicator .ct-btn-icon {
    width: 14px;
    height: 14px;
}

/* Toolbar: turn controls, then encounter setup, then what ends a fight. */
.combat-tracker-page .combat-top-nav-actions {
    flex-wrap: wrap;
    row-gap: 6px;
    column-gap: 10px;
}

.combat-tracker-page .combat-toolbar-group {
    display: flex;
    align-items: center;
    gap: 6px;
}

/* A quiet divider rather than a rule between every button. */
.combat-tracker-page .combat-toolbar-group + .combat-toolbar-group {
    padding-left: 10px;
    border-left: 1px solid color-mix(in srgb, var(--text-light) 22%, transparent);
}

.combat-tracker-page .combat-round-display-wrapper {
    gap: 6px;
    margin-right: 2px;
}

.combat-tracker-page .combat-round-label {
    font-size: 12px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--text-dim);
}

.combat-tracker-page .combat-round-value {
    font-size: 15px;
}

/* Labels stay readable rather than shrinking as the window narrows. */
.combat-tracker-page .combat-nav-btn {
    min-height: 28px;
    font-size: 12px;
}

.combat-tracker-page #next-turn-btn {
    font-weight: 700;
}

/* Clear ends the encounter: kept apart, and marked. */
.combat-tracker-page .combat-toolbar-danger #clear-combat-btn {
    border-color: var(--danger-color, #ff6b6b);
    color: var(--danger-color, #ff6b6b);
}

.combat-tracker-page .combat-toolbar-danger #clear-combat-btn:hover {
    background: color-mix(in srgb, var(--danger-color, #ff6b6b) 20%, transparent);
    color: var(--text-light);
}

/* Artwork and state are decoration: they do not animate, and nothing here
   moves for a reader who asked for less motion. */
@media (prefers-reduced-motion: reduce) {
    .ct-tcg .combat-carousel .item-card,
    .ct-tcg .combat-hp-bar {
        transition: none;
    }
}

/* ⚠️ The toolbar could not wrap, whatever flex-wrap said: the shared nav bar
   gives its actions `flex: 0 0 auto` and the default `min-width: auto`, so
   the row stayed at its content width and the bar scrolled sideways instead
   — in a 620px tracker window the round counter was off the left edge. It
   may shrink now, which is what lets the groups wrap into rows. */
.combat-tracker-page .top-nav-bar {
    flex-wrap: wrap;
    row-gap: 6px;
}

.combat-tracker-page .combat-top-nav-actions {
    flex: 1 1 auto;
    min-width: 0;
    justify-content: flex-end;
}

/* ----------------------------------------------------------------------------
   The map beside the roster, not under it

   The split was stacked — roster above, map below — which spent the window's
   height on two half-height panels and pushed the map down as cards grew.
   The roster is a column of cards down one side; the map takes the rest.
   (Owner, 2026-09-19: "you didnt move the map to the side".)

   Below 900px there is no room for two columns, so it stacks as before.
   ---------------------------------------------------------------------------- */

.combat-tracker-page .combat-split-view {
    flex-direction: row;
    align-items: stretch;
    overflow: hidden;
}

/* ⚠️ The width cannot come from --ct-card-width: that variable lives on
   .ct-tcg, which is *inside* this panel, so the panel never sees it. The
   density says how wide the column is. */
.combat-tracker-page .combat-split-view > .combat-tracker-panel {
    flex: 0 0 auto;
    width: 340px;
    max-height: none;
    height: 100%;
}

.combat-tracker-page .combat-split-view > .combat-tracker-panel:has(.ct-tcg[data-density="comfortable"]) {
    width: 380px;
}

/* One card wide: the roster reads down the side. */
.combat-tracker-page .combat-carousel-container.ct-tcg {
    flex: 1 1 auto;
    overflow-x: hidden;
    overflow-y: auto;
    padding: 10px;
}

.combat-tracker-page .ct-tcg .combat-carousel {
    flex-direction: column;
    gap: 10px;
    min-width: 0;
}

/* ⚠️ flex-basis is the main axis, and the main axis here is the height: the
   card's `flex: 0 0 300px` from the horizontal layout became a 300px-tall
   card, clipping everything below the saves. In a column a card is as tall
   as it needs to be. */
.combat-tracker-page .ct-tcg .combat-carousel .item-card {
    flex: 0 0 auto;
    width: 100%;
    max-width: none;
}

.combat-tracker-page .battle-map-panel {
    flex: 1 1 auto;
    min-width: 0;
}

@media (max-width: 900px) {
    .combat-tracker-page .combat-split-view {
        flex-direction: column;
        overflow-y: auto;
    }

    .combat-tracker-page .combat-split-view > .combat-tracker-panel {
        width: auto;
        max-height: 75vh;
        height: auto;
    }

    .combat-tracker-page .ct-tcg .combat-carousel {
        flex-direction: row;
    }

    .combat-tracker-page .ct-tcg .combat-carousel .item-card {
        width: var(--ct-card-width);
    }

    .combat-tracker-page .combat-carousel-container.ct-tcg {
        overflow-x: auto;
        overflow-y: hidden;
    }
}

/* ----------------------------------------------------------------------------
   Carried through from the whole-tracker preview (S-38 §5, visual reference)
   ---------------------------------------------------------------------------- */

/* Resource controls say what they are and what is left of them. Icon-only
   buttons made a GM guess which glyph was spells and which was features. */
.ct-tcg .spells-button-container {
    display: grid;
    /* Two per row rather than three squeezed: a truncated "Featur…" is
       worse than a second row. */
    grid-template-columns: repeat(auto-fit, minmax(104px, 1fr));
    gap: 5px;
}

.ct-tcg .spells-button-container .btn {
    gap: 5px;
    justify-content: flex-start;
    padding: 5px 8px;
}

.ct-tcg .ct-btn-label {
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.01em;
    white-space: nowrap;
}

/* Hit points: the number that changes is the one you read across the table. */
.ct-tcg .combat-hp-current {
    font-size: 19px;
}

.ct-tcg .combat-hp-max {
    font-size: 13px;
    opacity: 0.7;
}

/* Stat labels are words now (Armour, Initiative), so they get the room. */
.ct-tcg .combat-card-header-right {
    grid-template-columns: repeat(3, minmax(0, 1fr));
}

.ct-tcg .combat-initiative-label {
    font-size: 12px;
    letter-spacing: 0.04em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 100%;
}

/* The roster and the map read as one tracker: same frame, same corner. */
.combat-tracker-page .battle-map-panel,
.combat-tracker-page .combat-tracker-panel {
    border: 1px solid var(--ct-frame-soft);
    border-radius: 10px;
    background: color-mix(in srgb, var(--surface-panel) 30%, var(--ct-body, var(--surface-base)));
}

.combat-tracker-page .battle-map-header {
    border-bottom: 1px solid var(--ct-frame-soft);
    background: transparent;
}

.combat-tracker-page .battle-map-title {
    font-size: 12px;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-dim);
}

.combat-tracker-page .defeated-enemies-section {
    border-top: 1px solid var(--ct-frame-soft);
    background: transparent;
}

/* Attack selection: scoped to this popup, preserving shared modal consumers. */
.combat-tracker-page #items-modal,
.combat-tracker-page #spells-modal,
.combat-tracker-page #target-modal,
.combat-tracker-page #features-modal {
    background: color-mix(in srgb, var(--surface-base) 58%, transparent);
    padding: 20px;
    box-sizing: border-box;
}

.combat-tracker-page #items-modal .combat-modal-content,
.combat-tracker-page #spells-modal .combat-modal-content,
.combat-tracker-page #target-modal .combat-modal-content,
.combat-tracker-page #features-modal .combat-modal-content {
    width: min(680px, 100%);
    max-width: 100%;
    max-height: calc(100dvh - 40px);
    padding: 22px;
    box-sizing: border-box;
    background: var(--surface-base);
    border: 1px solid var(--primary-color);
    border-radius: 12px;
    box-shadow: 0 0 24px var(--shadow-primary-25), 0 16px 48px var(--shadow-ambient-55);
}

.combat-tracker-page #items-modal .combat-modal-header,
.combat-tracker-page #spells-modal .combat-modal-header,
.combat-tracker-page #target-modal .combat-modal-header,
.combat-tracker-page #features-modal .combat-modal-header {
    gap: 16px;
    margin-bottom: 18px;
    padding-bottom: 16px;
    border-bottom: 1px solid var(--border-color);
}

.combat-tracker-page #items-modal .combat-modal-title,
.combat-tracker-page #spells-modal .combat-modal-title,
.combat-tracker-page #target-modal .combat-modal-title,
.combat-tracker-page #features-modal .combat-modal-title {
    font: 400 23px/1.25 Georgia, "Times New Roman", serif;
    color: var(--text-light);
    overflow-wrap: anywhere;
}

.combat-tracker-page #items-modal .combat-modal-close,
.combat-tracker-page #spells-modal .combat-modal-close,
.combat-tracker-page #target-modal .combat-modal-close,
.combat-tracker-page #features-modal .combat-modal-close {
    flex: 0 0 32px;
    width: 32px;
    height: 32px;
    border: 1px solid var(--border-color);
    border-radius: 6px;
    background: var(--surface-panel);
    color: var(--text-light);
    font-size: 22px;
}

.combat-tracker-page #items-modal .items-modal-grid,
.combat-tracker-page #spells-modal .items-modal-grid {
    grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
    gap: 12px;
}

.combat-tracker-page #items-modal .item-option-modal,
.combat-tracker-page #spells-modal .item-option-modal {
    min-width: 0;
    padding: 16px;
    gap: 10px;
    background: var(--surface-panel);
    border: 1px solid var(--border-color);
    border-radius: 8px;
    cursor: default;
    transition: border-color 0.15s ease;
}

.combat-tracker-page #items-modal .item-option-modal:hover,
.combat-tracker-page #spells-modal .item-option-modal:hover {
    transform: none;
    background: var(--surface-panel);
    border-color: var(--primary-color);
}

.combat-tracker-page #items-modal .item-option-name,
.combat-tracker-page #spells-modal .item-option-name {
    margin: 0;
    font-size: 17px;
    line-height: 1.3;
    color: var(--text-light);
    overflow-wrap: anywhere;
}

.combat-tracker-page #items-modal .item-option-damage,
.combat-tracker-page #spells-modal .item-option-damage {
    margin: 0 0 4px;
    font-size: 14px;
    line-height: 1.5;
    color: var(--text-dim);
    opacity: 1;
    overflow-wrap: anywhere;
}

.combat-tracker-page #items-modal .combat-item-roll-btn,
.combat-tracker-page #spells-modal .combat-item-roll-btn {
    min-height: 38px;
    padding: 8px 12px;
    font-size: 14px;
    border: 1px solid var(--primary-color);
    border-radius: 6px;
    background: var(--surface-base);
    color: var(--primary-color);
    box-shadow: none;
}

.combat-tracker-page #items-modal .combat-item-roll-btn:hover,
.combat-tracker-page #spells-modal .combat-item-roll-btn:hover {
    background: var(--accent-primary-20);
    box-shadow: 0 0 12px var(--shadow-primary-25);
}

.combat-tracker-page #items-modal button:focus-visible,
.combat-tracker-page #spells-modal button:focus-visible,
.combat-tracker-page #target-modal button:focus-visible,
.combat-tracker-page #features-modal button:focus-visible {
    outline: 2px solid var(--primary-color);
    outline-offset: 3px;
}

/* Spell markup has legacy inline presentation, including hover handlers.
   Override only presentation here, retaining casting and level filters. */
.combat-tracker-page #spells-modal .spell-option,
.combat-tracker-page #target-modal .target-option {
    background: var(--surface-panel) !important;
    border: 1px solid var(--border-color) !important;
    border-radius: 8px !important;
    padding: 16px !important;
    gap: 10px !important;
    transform: none !important;
}
.combat-tracker-page #spells-modal .spell-option:hover,
.combat-tracker-page #target-modal .target-option:hover {
    border-color: var(--primary-color) !important;
}
.combat-tracker-page #spells-modal .spell-option > div,
.combat-tracker-page #target-modal .target-option > div {
    font-size: 14px !important;
    line-height: 1.5 !important;
    opacity: 1 !important;
    color: var(--text-dim) !important;
    overflow-wrap: anywhere;
}
.combat-tracker-page #spells-modal .spell-option > div:first-child,
.combat-tracker-page #target-modal .target-option > div:first-child {
    font-size: 17px !important;
    color: var(--text-light) !important;
}
.combat-tracker-page #spells-modal-content > div:has(> .spell-option),
.combat-tracker-page #target-modal-content > div:has(> .target-option) {
    grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr)) !important;
    gap: 12px !important;
}
.combat-tracker-page #spells-modal-content > div:has(.spell-level-filter-btn) {
    background: var(--surface-panel) !important;
    border-color: var(--border-color) !important;
    padding: 12px !important;
}
.combat-tracker-page #spells-modal-content > div:has(.spell-level-filter-btn) > div {
    font-size: 13px !important;
    opacity: 1 !important;
}
.combat-tracker-page #spells-modal .cast-spell-modal-btn,
.combat-tracker-page #spells-modal .spell-level-filter-btn,
.combat-tracker-page #target-modal #done-target-btn,
.combat-tracker-page #target-modal #no-target-btn {
    background: var(--surface-base) !important;
    color: var(--text-light) !important;
    border: 1px solid var(--border-color) !important;
    border-radius: 6px !important;
    font-size: 14px !important;
    padding: 8px 12px !important;
    min-height: 36px;
}
.combat-tracker-page #spells-modal .spell-level-filter-btn[aria-pressed="true"],
.combat-tracker-page #spells-modal .cast-spell-modal-btn:hover,
.combat-tracker-page #target-modal #done-target-btn:hover,
.combat-tracker-page #target-modal #no-target-btn:hover {
    border-color: var(--primary-color) !important;
    background: var(--accent-primary-20) !important;
    box-shadow: inset 0 -2px var(--primary-color);
}

/* Preview finish. These local surfaces use the chosen theme, without changing
   its palette or any shared card consumer. Define panel tokens on the page as
   well as the card root: siblings cannot inherit variables from .ct-tcg. */
.combat-tracker-page,
.ct-tcg {
    --ct-body: var(--surface-base);
    --ct-panel: var(--surface-panel);
    --ct-frame-soft: var(--secondary-color);
    --ct-frame: var(--primary-color);
}

.combat-tracker-page.characters-page {
    display: flex;
    flex-direction: column;
    height: 100dvh;
    min-height: 0;
    overflow: hidden;
    background: var(--surface-base);
}

.combat-tracker-page .top-nav-bar.combat-top-nav-bar {
    flex: 0 0 auto;
    flex-direction: column;
    align-items: stretch;
    gap: 14px;
    padding: 20px 22px 16px !important;
    background: var(--ct-body);
    border-bottom: 1px solid var(--ct-frame-soft);
    box-shadow: none;
    backdrop-filter: none;
}

.combat-tracker-page .combat-top-nav-title {
    font-family: Georgia, "Times New Roman", serif;
    font-size: 26px;
    font-weight: 400;
    color: var(--text-light);
    line-height: 1.2;
}

.combat-tracker-page .combat-top-nav-actions {
    justify-content: flex-start;
    gap: 10px 16px;
}

.combat-tracker-page .combat-round-display-wrapper {
    padding-right: 12px;
    margin-right: 6px;
    border-right: 1px solid var(--ct-frame-soft);
}

.combat-tracker-page .combat-round-value {
    font-family: Georgia, "Times New Roman", serif;
    font-size: 24px;
    color: var(--text-light);
}

.combat-tracker-page .combat-nav-btn,
.combat-tracker-page .battle-map-select {
    min-height: 32px;
    padding: 6px 10px;
    font-size: 12px;
    border: 1px solid var(--ct-frame-soft);
    border-radius: 6px;
    background: var(--ct-panel);
    color: var(--text-light);
    box-shadow: none;
}

.combat-tracker-page #next-turn-btn {
    background: color-mix(in srgb, var(--primary-color) 24%, var(--ct-body));
    border-color: color-mix(in srgb, var(--primary-color) 65%, var(--ct-body));
    color: var(--text-light);
}

.combat-tracker-page .combat-nav-btn:hover {
    border-color: var(--primary-color);
    transform: none;
}

.combat-tracker-page.characters-page:has(.top-nav-bar) .combat-split-view {
    flex: 1 1 auto;
    height: auto;
    min-height: 0;
    width: 100%;
    gap: 18px;
    padding: 18px 22px;
}

.combat-tracker-page .combat-split-view > .combat-tracker-panel {
    flex: 1.15 1 0;
    width: auto;
    min-width: 0;
    min-height: 0;
    border: 0;
    background: transparent;
}

.combat-tracker-page .combat-split-view > .combat-tracker-panel:has(.ct-tcg[data-density="comfortable"]) {
    width: auto;
}

.combat-tracker-page .combat-carousel-container.ct-tcg {
    padding: 3px 10px 12px 3px;
    scrollbar-color: var(--ct-frame) transparent;
    overflow-x: auto;
    overflow-y: auto;
}

.combat-tracker-page .ct-tcg .combat-carousel {
    flex-direction: row;
    gap: 18px;
}

.combat-tracker-page .ct-tcg .combat-carousel .item-card {
    flex: 0 0 var(--ct-card-width);
    width: var(--ct-card-width);
    max-width: var(--ct-card-width);
}

.combat-tracker-page .battle-map-panel {
    flex: 1 1 0;
    border: 1px solid var(--ct-frame-soft);
    background: var(--ct-body);
    border-radius: 10px;
}

.combat-tracker-page .battle-map-header {
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    padding: 14px;
}

.combat-tracker-page .battle-map-header-left,
.combat-tracker-page .battle-map-controls {
    flex-wrap: wrap;
    gap: 8px;
    min-width: 0;
}

.combat-tracker-page .battle-map-select {
    max-width: 100%;
}

.combat-tracker-page .battle-map-toggle,
.combat-tracker-page .image-scale-label,
.combat-tracker-page .image-scale-value {
    font-size: 12px;
    color: var(--text-dim);
}

.combat-tracker-page .defeated-enemies-section {
    flex-shrink: 0;
    padding: 10px 0;
    color: var(--text-dim);
}

.ct-tcg .combat-carousel .item-card,
.ct-tcg.combat-card-preview .item-card {
    padding: 7px;
    border-width: 1px;
    border-radius: 12px;
    box-shadow: 0 4px 14px color-mix(in srgb, var(--surface-base) 50%, transparent);
}

.ct-tcg .combat-card-wrapper {
    border-radius: 6px;
}

.ct-tcg .combat-card-header-left {
    padding: 11px 12px 10px;
    gap: 5px;
    background: var(--ct-body);
}

.ct-tcg .combat-card-title-wrapper {
    font-size: 20px;
    font-weight: 400;
    line-height: 1.2;
}

.ct-tcg .combat-card-meta {
    color: var(--text-dim);
}

.ct-tcg .combat-image-container img {
    border: 0;
    border-radius: 0;
    box-shadow: none;
}

.ct-tcg .combat-card-header-right,
.ct-tcg .combat-card-stats-section,
.ct-tcg .combat-card-footer {
    background: var(--ct-body);
}

.ct-tcg .combat-card-header-right {
    padding: 12px 12px 10px;
    gap: 8px;
}

.ct-tcg .combat-stat-group-header {
    background: transparent;
    border: 0;
    border-right: 1px solid var(--ct-frame-soft);
    border-radius: 0;
    align-items: flex-start;
    padding: 0 4px;
    gap: 5px;
}

.ct-tcg .combat-stat-group-header:last-child {
    border-right: 0;
}

.ct-tcg .combat-initiative-value,
.ct-tcg .combat-hp-current {
    font-size: 23px;
}

.ct-tcg .combat-initiative-value:not([data-hp-color]):not([data-ac-modified="true"]) {
    color: var(--text-light);
}

.ct-tcg .combat-card-stats-section {
    padding: 4px 12px 12px;
    gap: 12px;
}

.ct-tcg .combat-save-pip {
    padding: 6px 0;
    gap: 3px;
    background: var(--ct-panel);
}

.ct-tcg .combat-section-panel {
    background: transparent;
    border: 0;
    border-top: 1px solid var(--ct-frame-soft);
    border-radius: 0;
    padding: 9px 0 0;
}

.ct-tcg .combat-condition-badge {
    max-width: 100%;
    flex-wrap: wrap;
    overflow-wrap: anywhere;
}

.ct-tcg .spells-button-container .btn,
.ct-tcg .combat-actions-row .btn {
    background: var(--ct-panel);
    border: 1px solid var(--ct-frame-soft);
    color: var(--text-light);
    box-shadow: none;
    border-radius: 5px;
    min-height: 32px;
}

.ct-tcg .spells-button-container .btn:hover,
.ct-tcg .combat-actions-row .btn:hover {
    border-color: var(--primary-color);
}

.ct-tcg .combat-actions-row .btn.active,
.ct-tcg .spells-button-container .btn.active {
    background: color-mix(in srgb, var(--accent-color) 25%, var(--ct-body));
    border-color: var(--accent-color);
    box-shadow: inset 0 -2px var(--accent-color);
}

.ct-tcg .combat-card-footer {
    padding: 10px 12px;
}

.ct-tcg .combat-carousel .item-card.current-turn,
.ct-tcg .combat-carousel .item-card.dice-tray-active {
    border-width: 1px;
}

.ct-tcg .combat-carousel .item-card.current-turn {
    box-shadow: 0 0 0 1px var(--primary-color);
}

.ct-tcg .item-card .btn:focus-visible,
.combat-tracker-page .combat-nav-btn:focus-visible,
.combat-tracker-page .battle-map-select:focus-visible {
    outline: 2px solid var(--primary-color);
    outline-offset: 2px;
}

@media (max-width: 900px) {
    .combat-tracker-page .combat-split-view > .combat-tracker-panel,
    .combat-tracker-page .combat-split-view > .combat-tracker-panel:has(.ct-tcg[data-density="comfortable"]) {
        width: 100%;
        flex: 0 0 auto;
        max-height: none;
    }

    .combat-tracker-page .battle-map-panel {
        flex: 1 0 320px;
    }

    .combat-tracker-page.characters-page:has(.top-nav-bar) .combat-split-view {
        padding: 12px;
        gap: 12px;
    }

    .combat-tracker-page .top-nav-bar.combat-top-nav-bar {
        padding: 14px 12px !important;
    }
}

/* Headers follow the preview's clear hierarchy and roomy, labelled controls. */
.combat-tracker-page .top-nav-bar.combat-top-nav-bar {
    gap: 18px;
    padding: 22px 24px 18px !important;
}
.combat-tracker-page .combat-top-nav-title {
    font-size: 30px;
}
.combat-tracker-page .combat-toolbar-group {
    gap: 8px;
}
.combat-tracker-page .combat-nav-btn {
    min-height: 36px;
    padding: 8px 12px;
    font-size: 13px;
    font-weight: 500;
    background: var(--surface-panel);
    border-color: var(--border-color);
}
.combat-tracker-page #next-turn-btn {
    background: var(--primary-color);
    color: var(--surface-base);
    border-color: var(--primary-color);
}
.combat-tracker-page .battle-map-header {
    flex-direction: column;
    align-items: stretch;
    padding: 16px;
    gap: 12px;
}
.combat-tracker-page .battle-map-header-left {
    justify-content: space-between;
}
.combat-tracker-page .battle-map-title {
    font: 400 20px/1.2 Georgia, "Times New Roman", serif;
    letter-spacing: normal;
    text-transform: none;
    color: var(--text-light);
}
.combat-tracker-page .battle-map-controls {
    justify-content: flex-start;
}
.combat-tracker-page #move-approval-toggle-wrap {
    order: 2;
    flex-basis: 100%;
    padding-top: 4px;
}
.combat-tracker-page #toggle-map-grid-btn[aria-pressed="true"] {
    border-color: var(--primary-color);
    background: var(--accent-primary-20);
    box-shadow: inset 0 -2px var(--primary-color);
}


/* The target rows' spans size with the rest of the window. Their colours are
   left as the renderer set them: the hit-point value's red or amber says how
   hurt the target is, and is not decoration. */
.combat-tracker-page #target-modal .target-option span {
    font-size: 14px !important;
}

/* Features: the same surfaces and text sizes as the weapon, spell and target
   windows. ⚠️ The toggle keeps its own colours — lit means the feature is on,
   and that state must stay readable at a glance. */
.combat-tracker-page #features-modal-content {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.combat-tracker-page #features-modal .feature-window-group {
    margin: 6px 0 0;
    font-size: 13px;
    letter-spacing: 0.08em;
    color: var(--text-dim);
}

.combat-tracker-page #features-modal .feature-window-row {
    gap: 12px;
    margin: 0;
    padding: 16px;
    background: var(--surface-panel);
    border: 1px solid var(--border-color);
    border-radius: 8px;
}

.combat-tracker-page #features-modal .feature-window-row.is-active {
    border-color: var(--primary-color);
}

.combat-tracker-page #features-modal .feature-window-main {
    gap: 4px;
}

.combat-tracker-page #features-modal .feature-window-name {
    font-size: 17px;
    line-height: 1.3;
    color: var(--text-light);
    overflow-wrap: anywhere;
}

.combat-tracker-page #features-modal .feature-window-text {
    font-size: 14px;
    line-height: 1.5;
    color: var(--text-dim);
    opacity: 1;
    overflow-wrap: anywhere;
}

.combat-tracker-page #features-modal .feature-window-uses,
.combat-tracker-page #features-modal .feature-window-armour {
    font-size: 14px;
    line-height: 1.5;
}

.combat-tracker-page #features-modal .feature-window-toggle {
    min-height: 36px;
    padding: 8px 12px;
    font-size: 14px;
    border-radius: 6px;
}


/* A target already rolled against, so a GM working through a group can see
   who they have covered. It stays clickable — hitting the same creature
   twice is a normal thing to do. */
.combat-tracker-page #target-modal .target-option.is-rolled {
    border-color: var(--primary-color) !important;
    background: var(--accent-primary-20) !important;
}

.combat-tracker-page #target-modal .target-option-mark {
    float: right;
    padding: 1px 8px;
    border: 1px solid var(--primary-color);
    border-radius: 999px;
    font-size: 12px;
    font-weight: 600;
    color: var(--primary-color);
}


/* pages/_characters-npcs.css */
/**
 * Characters & NPCs Pages
 * Character-select and NPC-select pages use form-list styles
 * Character-detail and NPC-detail pages use shared detail styles
 * 
 * When displaying items in character/npc detail modals, those items
 * should use the same .item-card styles from components/_cards.css
 * and form-list styles from pages/_form-list-pages.css
 */

body.characters-page {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    padding: 0;
    background: linear-gradient(135deg, var(--theme-color-2, var(--abyssal-dark)) 0%, var(--theme-color-1, var(--abyssal-purple)) 100%);
    background-attachment: fixed;
    color: var(--text-light, var(--abyssal-light));
    margin: 0;
    min-height: 100vh;
}

/* Combat tracker page (characters-page with top-nav-bar) - centered, NO sidebar padding */
body.characters-page:has(.top-nav-bar) {
    padding-top: 0 !important; /* No top banner, so no top padding needed */
    padding-left: 0 !important; /* NO sidebar padding - centered */
    padding-right: 0 !important; /* No right padding - centered */
    margin: 0;
}

/* Center combat tracker content */
body.characters-page:has(.top-nav-bar) .combat-split-view {
    max-width: 1800px; /* Max width for readability */
    margin: 0 auto; /* Center the content */
    padding: 8px 20px; /* Horizontal padding for content */
    box-sizing: border-box;
}

/* Characters page uses form-list styles for item cards */
/* The .item-card styles are shared via components/_cards.css */
/* When items are shown in detail modals, they use the same card styles */

.characters-page .inventory-db-card {
    background: color-mix(in srgb, var(--panel-75) 100%, transparent);
    backdrop-filter: blur(10px);
    border-radius: 8px;
    border-left: 4px solid var(--card-accent, var(--secondary-color));
    padding: 15px;
    position: relative;
    transition: transform 0.3s ease, box-shadow 0.3s ease;
    cursor: pointer;
}

.characters-page .inventory-db-card:hover {
    transform: translateY(-3px);
    box-shadow: 0 4px 20px color-mix(in srgb, var(--primary-color) 25%, transparent);
}

.characters-page .inventory-db-card .inventory-db-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: 10px;
    gap: 10px;
}

.characters-page .inventory-db-card .inventory-db-name {
    color: var(--primary-color, var(--abyssal-glow));
    font-size: 1.1em;
    font-weight: 600;
    margin-bottom: 5px;
}

.characters-page .inventory-db-card .inventory-db-body {
    font-size: 0.9em;
    color: var(--text-light, var(--abyssal-light));
    margin-top: 8px;
    line-height: 1.4;
}

.characters-page .inventory-db-card .inventory-db-edit-btn {
    background: var(--accent-primary-20);
    border: 2px solid var(--primary-color, var(--abyssal-glow));
    border-radius: 6px;
    padding: 6px 10px;
    color: var(--primary-color, var(--abyssal-glow));
    cursor: pointer;
    font-weight: 600;
    font-size: 0.85em;
    transition: background 0.2s ease;
    flex-shrink: 0;
}

.characters-page .inventory-db-card .inventory-db-edit-btn:hover {
    background: var(--accent-primary-35);
}

.characters-page .inventory-db-card .inventory-db-tag {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 4px;
    font-size: 0.75em;
    font-weight: 600;
    text-transform: uppercase;
}

/* Characters page CSS variable overrides */
.characters-page {
    --panel-98: color-mix(in srgb, var(--theme-color-2, var(--abyssal-dark)) 98%, transparent 2%);
    --panel-90: color-mix(in srgb, var(--theme-color-2, var(--abyssal-dark)) 90%, transparent 10%);
    --panel-75: color-mix(in srgb, var(--theme-color-2, var(--abyssal-dark)) 75%, transparent 25%);
    --panel-60: color-mix(in srgb, var(--theme-color-2, var(--abyssal-dark)) 60%, transparent 40%);
    --panel-40: color-mix(in srgb, var(--theme-color-1, var(--abyssal-purple)) 40%, transparent 60%);
    --accent-primary-20: color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 20%, transparent 80%);
    --accent-primary-35: color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 35%, transparent 65%);
    --accent-secondary-20: color-mix(in srgb, var(--secondary-color, var(--abyssal-glow)) 20%, transparent 80%);
    --accent-secondary-35: color-mix(in srgb, var(--secondary-color, var(--abyssal-glow)) 35%, transparent 65%);
    --accent-accent-20: color-mix(in srgb, var(--accent-color, var(--abyssal-accent)) 20%, transparent 80%);
    --accent-accent-35: color-mix(in srgb, var(--accent-color, var(--abyssal-accent)) 35%, transparent 65%);
}

/* Character detail page - items shown should use form-list card styles */
/* Character-detail and NPC-detail pages share the same structure */
/* All editing forms use shared form styles from components/_forms.css */

/* ── Characters waiting to join (S-21 FR-11.4) ─────────────────────────────
   A player's saved character does not exist in the campaign until whoever
   runs it approves, so this sits above the roster it is asking to join and
   is absent entirely when nothing is waiting. Theme variables throughout:
   the panel has to read in every palette (S-76 FR-2). */

.import-requests {
    margin: 0 0 18px;
    padding: 14px 16px;
    background: var(--panel-75, rgba(0, 0, 0, 0.35));
    border: 1px solid var(--accent-primary-35, var(--abyssal-glow));
    border-radius: 10px;
}

.import-requests-title {
    margin: 0 0 10px;
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--text-light);
}

.import-request {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    padding: 8px 0;
    border-top: 1px solid var(--accent-primary-20, rgba(255, 255, 255, 0.1));
}

.import-request:first-of-type {
    border-top: 0;
}

.import-request-text {
    font-size: 0.88rem;
    color: var(--text-light);
}

.import-request-actions {
    display: flex;
    gap: 8px;
}

/* The player's side of the same row: what is happening, without a control
   they are not allowed to use. */
.import-request-waiting {
    font-size: 0.8rem;
    opacity: 0.75;
    color: var(--text-light);
}


/* pages/_character-detail.css */
/**
 * Character Detail Page Styles
 * Trading card-inspired edit form styling
 */

/* XP Progress Bar - Clickable with hover effect */
/* Use !important to override inline styles in iframe/window contexts */
/* This works in both iframe and window contexts */
.xp-progress-bar {
    cursor: pointer !important;
    transition: all 0.2s ease !important;
    position: relative !important;
    pointer-events: auto !important;
}

.xp-progress-bar:hover {
    background: rgba(0, 0, 0, 0.5) !important;
    border-color: var(--abyssal-teal) !important;
    box-shadow: 0 0 8px rgba(76, 211, 194, 0.4) !important;
    transform: translateY(-1px) !important;
}

.xp-progress-bar:active {
    background: rgba(0, 0, 0, 0.6) !important;
    border-color: var(--abyssal-glow) !important;
    transform: translateY(0) scale(0.98) !important;
    box-shadow: 0 0 12px rgba(76, 211, 194, 0.5) !important;
}

/* Character Detail Header Actions */
.character-detail-header-actions,
.npc-detail-header-actions {
    display: flex;
    gap: 8px;
    align-items: center;
}

/* Back button, Level Up button, and Edit button - all use same style */
.go-back-btn,
.character-detail-header-actions .level-up-btn,
.character-detail-header-actions .edit-item-btn,
.npc-detail-header-actions .level-up-btn,
.npc-detail-header-actions .edit-item-btn {
    background: rgba(168, 85, 247, 0.2);
    border: 2px solid var(--abyssal-glow);
    border-radius: 6px;
    padding: 8px 12px;
    color: var(--abyssal-glow);
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 0.9em;
    font-weight: 600;
    transition: all 0.2s ease;
}

.go-back-btn:hover,
.character-detail-header-actions .level-up-btn:hover,
.character-detail-header-actions .edit-item-btn:hover,
.npc-detail-header-actions .level-up-btn:hover,
.npc-detail-header-actions .edit-item-btn:hover {
    background: rgba(168, 85, 247, 0.4);
}

/* Trading Card Style Modal for Character Edit */
#modal.character-edit-modal .modal-content {
    max-width: 1000px;
    width: 90%;
    max-height: 85vh;
    background: linear-gradient(135deg, 
        color-mix(in srgb, var(--theme-color-2, var(--abyssal-dark)) 98%, transparent) 0%, 
        color-mix(in srgb, var(--surface-panel, rgba(45, 45, 58, 0.95)) 98%, transparent) 50%,
        color-mix(in srgb, var(--theme-color-2, var(--abyssal-dark)) 98%, transparent) 100%);
    border: 3px solid var(--accent-color, var(--abyssal-accent));
    border-radius: 20px;
    padding: 0;
    box-shadow: 
        0 0 30px color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 40%, transparent),
        0 20px 60px rgba(0, 0, 0, 0.6),
        inset 0 0 20px color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 10%, transparent);
    position: relative;
    overflow-y: auto;
    overflow-x: hidden;
    transform-style: preserve-3d;
}

/* Card-like header section */
#modal.character-edit-modal .modal-content::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 120px;
    background: linear-gradient(180deg, 
        color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 30%, transparent) 0%,
        color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 10%, transparent) 50%,
        transparent 100%);
    pointer-events: none;
    z-index: 0;
}

/* Card title area */
#modal.character-edit-modal #modal-title {
    position: relative;
    z-index: 1;
    padding: 20px 25px 15px;
    margin: 0;
    font-size: 1.5em;
    font-weight: 700;
    text-align: center;
    color: var(--primary-color, var(--abyssal-glow));
    text-shadow: 
        0 0 10px color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 50%, transparent),
        0 2px 4px rgba(0, 0, 0, 0.5);
    border-bottom: 2px solid color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 30%, transparent);
    background: linear-gradient(180deg, 
        color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 15%, transparent) 0%,
        transparent 100%);
}

/* Form container with card-like styling */
#modal.character-edit-modal #item-form {
    padding: 25px;
    position: relative;
    z-index: 1;
    background: transparent;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

/* Form groups with card section styling - ALL ROUNDED AND SAME COLOR */
#modal.character-edit-modal .form-group {
    margin: 0;
    padding: 12px;
    background: color-mix(in srgb, var(--theme-color-2, var(--abyssal-dark)) 30%, transparent);
    border: 1px solid color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 20%, transparent);
    border-radius: 8px;
    transition: all 0.3s ease;
}

#modal.character-edit-modal .form-group:hover {
    background: color-mix(in srgb, var(--theme-color-2, var(--abyssal-dark)) 50%, transparent);
    border-color: color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 40%, transparent);
    box-shadow: 0 0 10px color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 20%, transparent);
}

/* Ensure all grid containers and their children are rounded */
#modal.character-edit-modal [style*="grid-template-columns"] {
    gap: 12px !important;
}

#modal.character-edit-modal [style*="grid-template-columns"] > * {
    border-radius: 8px !important;
    background: color-mix(in srgb, var(--theme-color-2, var(--abyssal-dark)) 30%, transparent) !important;
    border: 1px solid color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 20%, transparent) !important;
    padding: 12px !important;
    transition: all 0.3s ease !important;
}

#modal.character-edit-modal [style*="grid-template-columns"] > *:hover {
    background: color-mix(in srgb, var(--theme-color-2, var(--abyssal-dark)) 50%, transparent) !important;
    border-color: color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 40%, transparent) !important;
    box-shadow: 0 0 10px color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 20%, transparent) !important;
}

/* Labels with card-style typography */
#modal.character-edit-modal .form-group label {
    display: block;
    font-size: 0.8em;
    font-weight: 600;
    margin-bottom: 6px;
    color: var(--primary-color, var(--abyssal-glow));
    text-transform: uppercase;
    letter-spacing: 0.5px;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
}

/* Input fields with card-style appearance - ALL ROUNDED */
#modal.character-edit-modal input[type="text"],
#modal.character-edit-modal input[type="number"],
#modal.character-edit-modal select,
#modal.character-edit-modal textarea {
    width: 100%;
    padding: 8px 12px;
    font-size: 0.9em;
    background: rgba(0, 0, 0, 0.4);
    border: 1px solid color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 30%, transparent);
    border-radius: 8px !important;
    color: var(--text-light, #ffffff);
    transition: all 0.3s ease;
    font-family: inherit;
}

#modal.character-edit-modal input[type="text"]:focus,
#modal.character-edit-modal input[type="number"]:focus,
#modal.character-edit-modal select:focus,
#modal.character-edit-modal textarea:focus {
    outline: none;
    border-color: var(--primary-color, var(--abyssal-glow));
    background: rgba(0, 0, 0, 0.6);
    box-shadow: 
        0 0 10px color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 30%, transparent),
        inset 0 0 10px color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 10%, transparent);
}

/* Select dropdowns */
#modal.character-edit-modal select {
    cursor: pointer;
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23a855f7' d='M6 9L1 4h10z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 10px center;
    padding-right: 30px;
}

/* Textarea */
#modal.character-edit-modal textarea {
    resize: vertical;
    min-height: 80px;
    font-family: inherit;
}

/* Grid layouts - already handled above */

/* Image preview with card frame - ROUNDED */
#modal.character-edit-modal #image-preview {
    margin-top: 8px;
    padding: 12px;
    background: color-mix(in srgb, var(--theme-color-2, var(--abyssal-dark)) 30%, transparent);
    border: 1px solid color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 20%, transparent);
    border-radius: 8px !important;
    min-height: 120px;
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative;
    overflow: hidden;
}

#modal.character-edit-modal #image-preview img {
    max-width: 100%;
    max-height: 200px;
    border-radius: 6px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
}

/* Checkbox labels (skill proficiencies, etc.) - ROUNDED AND SAME COLOR */
#modal.character-edit-modal .checkbox-label {
    padding: 6px 10px;
    background: color-mix(in srgb, var(--theme-color-2, var(--abyssal-dark)) 30%, transparent);
    border: 1px solid color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 20%, transparent);
    border-radius: 8px !important;
    transition: all 0.2s ease;
    font-size: 0.85em;
}

#modal.character-edit-modal .checkbox-label:hover {
    background: color-mix(in srgb, var(--theme-color-2, var(--abyssal-dark)) 40%, transparent);
    border-color: color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 40%, transparent);
}

#modal.character-edit-modal .checkbox-label input[type="checkbox"] {
    margin-right: 6px;
    accent-color: var(--primary-color, var(--abyssal-glow));
}

/* Card-style button section at bottom */
#modal.character-edit-modal .form-group:last-of-type,
#modal.character-edit-modal [style*="justify-content: flex-end"] {
    margin-top: 20px;
    padding: 20px 0 0;
    border-top: 2px solid color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 30%, transparent);
    background: transparent;
    border-radius: 0;
}

/* Buttons with card-style appearance */
#modal.character-edit-modal .btn {
    padding: 12px 24px;
    font-size: 0.95em;
    font-weight: 600;
    border-radius: 8px;
    transition: all 0.3s ease;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
}

#modal.character-edit-modal .btn-primary {
    background: linear-gradient(135deg, var(--primary-color, var(--abyssal-glow)) 0%, color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 80%, transparent) 100%);
    border: 2px solid var(--primary-color, var(--abyssal-glow));
    color: var(--text-dark, #1a1a2e);
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.2);
}

#modal.character-edit-modal .btn-primary:hover {
    background: linear-gradient(135deg, color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 90%, transparent) 0%, var(--primary-color, var(--abyssal-glow)) 100%);
    box-shadow: 
        0 0 20px color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 50%, transparent),
        0 6px 16px rgba(0, 0, 0, 0.4);
    transform: translateY(-2px);
}

#modal.character-edit-modal .btn-secondary {
    background: color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 20%, transparent);
    border: 2px solid var(--primary-color, var(--abyssal-glow));
    color: var(--primary-color, var(--abyssal-glow));
}

#modal.character-edit-modal .btn-secondary:hover {
    background: color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 40%, transparent);
    box-shadow: 0 0 15px color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 30%, transparent);
}

/* Scrollbar styling for card aesthetic - ALWAYS VISIBLE */
#modal.character-edit-modal .modal-content {
    scrollbar-width: thin;
    scrollbar-color: color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 50%, transparent) rgba(0, 0, 0, 0.2);
}

#modal.character-edit-modal .modal-content::-webkit-scrollbar {
    width: 12px;
}

#modal.character-edit-modal .modal-content::-webkit-scrollbar-track {
    background: rgba(0, 0, 0, 0.3);
    border-radius: 6px;
    margin: 5px;
}

#modal.character-edit-modal .modal-content::-webkit-scrollbar-thumb {
    background: color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 50%, transparent);
    border-radius: 6px;
    border: 2px solid rgba(0, 0, 0, 0.2);
    min-height: 40px;
}

#modal.character-edit-modal .modal-content::-webkit-scrollbar-thumb:hover {
    background: color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 70%, transparent);
}

/* Ensure scrollbar is always visible when content overflows */
#modal.character-edit-modal .modal-content {
    overflow-y: auto !important;
    overflow-x: hidden !important;
}

/* Special styling for ability scores section (card stats) */
#modal.character-edit-modal [style*="grid-template-columns: repeat(6"] {
    gap: 8px !important;
}

#modal.character-edit-modal [style*="grid-template-columns: repeat(6"] .form-group {
    text-align: center;
    padding: 10px 8px;
}

#modal.character-edit-modal [style*="grid-template-columns: repeat(6"] .form-group label {
    font-size: 0.7em;
    margin-bottom: 4px;
}

#modal.character-edit-modal [style*="grid-template-columns: repeat(6"] input {
    text-align: center;
    font-weight: 600;
    font-size: 1em;
}

/* Spell slots section with card-style grid - ROUNDED AND SAME COLOR */
#modal.character-edit-modal #spell-slot-inputs {
    background: color-mix(in srgb, var(--theme-color-2, var(--abyssal-dark)) 30%, transparent);
    padding: 12px;
    border-radius: 8px !important;
    border: 1px solid color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 20%, transparent);
}

/* Skill proficiencies grid - ROUNDED AND SAME COLOR */
#modal.character-edit-modal [style*="grid-template-columns: repeat(auto-fit"] {
    background: color-mix(in srgb, var(--theme-color-2, var(--abyssal-dark)) 30%, transparent);
    padding: 12px;
    border-radius: 8px !important;
    border: 1px solid color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 20%, transparent);
}

/* Custom input fields (race, class, background) */
#modal.character-edit-modal input[id*="-custom"] {
    margin-top: 8px;
    border-style: dashed;
    border-color: color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 40%, transparent);
}

/* File input styling - ROUNDED */
#modal.character-edit-modal input[type="file"] {
    padding: 8px;
    background: rgba(0, 0, 0, 0.4);
    border: 1px dashed color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 30%, transparent);
    border-radius: 8px !important;
    color: var(--text-light, #ffffff);
    cursor: pointer;
    transition: all 0.3s ease;
}

#modal.character-edit-modal input[type="file"]:hover {
    border-color: color-mix(in srgb, var(--primary-color, var(--abyssal-glow)) 50%, transparent);
    background: rgba(0, 0, 0, 0.4);
}

/* Required field indicator */
#modal.character-edit-modal input[required] {
    border-left: 3px solid var(--primary-color, var(--abyssal-glow));
}

/* Responsive adjustments */
@media (max-width: 768px) {
    #modal.character-edit-modal .modal-content {
        width: 95%;
        max-height: 90vh;
        padding: 0;
    }
    
    #modal.character-edit-modal #item-form {
        padding: 20px 15px;
    }
    
    #modal.character-edit-modal #modal-title {
        font-size: 1.3em;
        padding: 15px 20px 12px;
    }
}
/* An entry that came in with an imported character and matched nothing this
   campaign holds (S-21 FR-11.5). It is a label, not an assignment: there is
   no library entry behind it. Marked rather than hidden, because the person
   who can fix it is the one reading the sheet. */
.unresolved-mark {
    margin-left: 8px;
    padding: 1px 7px;
    border: 1px solid var(--accent-color, var(--abyssal-accent));
    border-radius: 999px;
    background: color-mix(in srgb, var(--accent-color, var(--abyssal-accent)) 18%, transparent 82%);
    color: var(--text-light);
    font-size: 0.7em;
    font-weight: 600;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    text-decoration: none;
    vertical-align: middle;
    white-space: nowrap;
}


/* pages/_npc-detail-content.css */
/**
 * NPC Detail Content Styles
 *
 * Styles extracted from inline JS template literals in npc-detail.js
 * Used for dynamically generated NPC detail content
 */

/* ==========================================================================
   Combat Stats Panel
   ========================================================================== */

.npc-combat-stats-panel {
    display: flex;
    flex-direction: column;
    gap: 8px;
    height: 100%;
    width: 100%;
}

.npc-combat-panel {
    background: rgba(27, 42, 106, 0.3);
    border-radius: 6px;
    border: 2px solid var(--abyssal-glow);
    padding: 8px;
    flex: 0 0 auto;
    width: 100%;
}

.npc-combat-panel-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 6px;
}

.npc-combat-panel-title {
    color: var(--abyssal-glow);
    font-size: 0.85em;
    font-weight: 600;
}

.npc-combat-rows {
    display: flex;
    flex-direction: column;
    gap: 3px;
}

/* ==========================================================================
   Stat Rows
   ========================================================================== */

.npc-stat-row {
    padding: 8px;
    background: rgba(27, 42, 106, 0.4);
    border-radius: 3px;
    border-left: 2px solid var(--abyssal-teal);
}

.npc-stat-row-inner {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 4px;
}

.npc-stat-row-simple {
    padding: 5px 8px;
    background: rgba(27, 42, 106, 0.4);
    border-radius: 3px;
    border-left: 2px solid var(--abyssal-teal);
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.npc-stat-row-glow {
    padding: 5px 8px;
    background: rgba(27, 42, 106, 0.4);
    border-radius: 3px;
    margin-bottom: 6px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    border-left: 2px solid var(--abyssal-glow);
}

.npc-stat-label {
    color: var(--abyssal-light);
    font-size: 0.8em;
}

.npc-stat-label-glow {
    color: var(--abyssal-glow);
    font-size: 0.8em;
}

.npc-stat-value {
    font-size: 0.85em;
    font-weight: 600;
    color: var(--abyssal-light);
    min-width: 40px;
    text-align: right;
}

.npc-stat-value-highlight {
    font-size: 0.85em;
    font-weight: 600;
    color: var(--abyssal-glow);
}

/* AC Display - Simple (base AC only) */
.npc-ac-row {
    padding: 8px;
    background: rgba(27, 42, 106, 0.4);
    border-radius: 3px;
    border-left: 2px solid var(--abyssal-teal);
}

.npc-ac-row-inner {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.npc-ac-label {
    color: var(--abyssal-light);
    font-size: 0.8em;
}

.npc-ac-value {
    font-size: 0.85em;
    font-weight: 600;
    color: var(--abyssal-light);
}

/* ==========================================================================
   AC Display
   ========================================================================== */

.npc-ac-container {
    display: flex;
    align-items: center;
    gap: 8px;
}

.npc-ac-column {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
}

.npc-ac-value {
    font-size: 0.85em;
    font-weight: 600;
}

.npc-ac-value--modified {
    color: var(--abyssal-glow);
}

.npc-ac-value--base {
    font-size: 0.75em;
    font-weight: 600;
    color: var(--abyssal-light);
    opacity: 0.7;
}

.npc-ac-separator {
    font-size: 0.75em;
    color: var(--abyssal-light);
    opacity: 0.6;
}

/* ==========================================================================
   HP Display
   ========================================================================== */

.npc-hp-container {
    display: flex;
    align-items: center;
    gap: 12px;
}

.npc-hp-column {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
}

.npc-hp-value {
    font-size: 0.85em;
    font-weight: 600;
}

.npc-hp-separator {
    font-size: 0.85em;
    font-weight: 600;
    color: var(--abyssal-light);
}

/* HP Bar */
.npc-hp-bar {
    background: rgba(0, 0, 0, 0.3);
    border-radius: 3px;
    height: 6px;
    overflow: hidden;
}

.npc-hp-bar-fill {
    height: 100%;
    transition: width 0.3s ease;
}

.npc-hp-bar-fill--healthy {
    background: linear-gradient(90deg, var(--abyssal-teal), var(--abyssal-glow));
}

.npc-hp-bar-fill--injured {
    background: linear-gradient(90deg, #f4a100, #ff6b00);
}

.npc-hp-bar-fill--critical {
    background: linear-gradient(90deg, #dc3545, #ff0000);
}

/* ==========================================================================
   Buttons
   ========================================================================== */

/* General Action Button */
.npc-action-btn {
    padding: 4px 8px;
    background: rgba(76, 211, 194, 0.2);
    border: 1px solid var(--abyssal-teal);
    border-radius: 4px;
    color: var(--abyssal-teal);
    cursor: pointer;
    font-size: 0.75em;
    font-weight: 600;
    transition: all 0.2s;
    width: 30px;
}

.npc-action-btn:hover {
    background: rgba(76, 211, 194, 0.4);
}

/* Set Value Button */
.npc-set-btn {
    padding: 4px 8px;
    background: rgba(20, 184, 166, 0.2);
    border: 1px solid var(--abyssal-teal);
    border-radius: 4px;
    color: var(--abyssal-teal);
    cursor: pointer;
    font-size: 0.75em;
    font-weight: 600;
    transition: all 0.2s;
    width: 30px;
}

.npc-set-btn:hover {
    background: rgba(20, 184, 166, 0.4);
}

/* Hit Dice Button */
.npc-hit-dice-btn {
    padding: 6px 12px;
    background: rgba(168, 85, 247, 0.2);
    border: 1px solid var(--abyssal-glow);
    border-radius: 4px;
    color: var(--abyssal-glow);
    cursor: pointer;
    font-size: 0.75em;
    font-weight: 600;
    transition: all 0.2s;
}

.npc-hit-dice-btn:hover {
    background: rgba(168, 85, 247, 0.4);
}

/* Rest Buttons */
.npc-rest-btn {
    padding: 4px 8px;
    background: rgba(168, 85, 247, 0.2);
    border: 1px solid var(--abyssal-glow);
    border-radius: 4px;
    color: var(--abyssal-glow);
    cursor: pointer;
    font-size: 0.75em;
    font-weight: 600;
    transition: all 0.2s;
}

.npc-rest-btn:hover {
    background: rgba(168, 85, 247, 0.4);
}

.npc-rest-btn--short {
    background: rgba(76, 211, 194, 0.15);
    border: 1px solid rgba(76, 211, 194, 0.3);
    color: var(--abyssal-teal);
}

.npc-rest-btn--short:hover {
    background: rgba(76, 211, 194, 0.3);
}

.npc-rest-btn--long {
    background: rgba(138, 43, 226, 0.15);
    border: 1px solid rgba(138, 43, 226, 0.3);
    color: var(--abyssal-glow);
}

.npc-rest-btn--long:hover {
    background: rgba(138, 43, 226, 0.3);
}

/* Equip Button */
.npc-equip-btn {
    padding: 6px 12px;
    background: rgba(20, 184, 166, 0.2);
    border: 1px solid var(--abyssal-teal);
    border-radius: 4px;
    color: var(--abyssal-teal);
    cursor: pointer;
    font-size: 0.85em;
    font-weight: 600;
    transition: all 0.2s;
}

.npc-equip-btn:hover {
    background: rgba(20, 184, 166, 0.4);
}

.npc-equip-btn--equipped {
    background: rgba(20, 184, 166, 0.4);
}

/* Remove Button */
.npc-remove-btn {
    padding: 6px 12px;
    background: rgba(236, 72, 153, 0.2);
    border: 1px solid var(--abyssal-accent);
    border-radius: 4px;
    color: var(--abyssal-accent);
    cursor: pointer;
    font-size: 0.85em;
    font-weight: 600;
    transition: all 0.2s;
}

.npc-remove-btn:hover {
    background: rgba(236, 72, 153, 0.4);
}

/* Quantity Buttons */
.npc-quantity-btn {
    width: 20px;
    height: 20px;
    padding: 0;
    border-radius: 3px;
    cursor: pointer;
    font-weight: 600;
    font-size: 0.75em;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
}

.npc-quantity-btn--increase {
    background: rgba(20, 184, 166, 0.2);
    border: 1px solid var(--abyssal-teal);
    color: var(--abyssal-teal);
}

.npc-quantity-btn--increase:hover {
    background: rgba(20, 184, 166, 0.4);
}

.npc-quantity-btn--decrease {
    background: rgba(236, 72, 153, 0.2);
    border: 1px solid var(--abyssal-accent);
    color: var(--abyssal-accent);
}

.npc-quantity-btn--decrease:hover {
    background: rgba(236, 72, 153, 0.4);
}

/* ==========================================================================
   Condition Badges
   ========================================================================== */

.npc-conditions-container {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
}

.npc-condition-badge {
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 4px 6px;
    background: rgba(168, 85, 247, 0.2);
    border: 1px solid var(--abyssal-glow);
    border-radius: 4px;
    cursor: pointer;
    font-size: 0.75em;
}

.npc-condition-badge:hover {
    background: rgba(168, 85, 247, 0.3);
}

.npc-condition-icon {
    /* Emoji icon styling */
}

.npc-condition-name {
    color: var(--abyssal-light);
}

.npc-condition-duration {
    color: var(--abyssal-teal);
    font-weight: 600;
    font-size: 0.9em;
}

.npc-condition-remove {
    padding: 0;
    background: none;
    border: none;
    color: var(--abyssal-light);
    cursor: pointer;
    font-size: 0.9em;
    opacity: 0.7;
    margin-left: 4px;
}

.npc-condition-remove:hover {
    opacity: 1;
}

/* ==========================================================================
   Ability Scores
   ========================================================================== */

.npc-abilities-container {
    background: rgba(27, 42, 106, 0.3);
    border-radius: 8px;
    border: 2px solid var(--abyssal-glow);
    padding: 10px;
    display: flex;
    flex-direction: column;
    height: 100%;
    width: 100%;
}

.npc-abilities-list {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.npc-ability-row {
    padding: 5px 8px;
    background: rgba(27, 42, 106, 0.4);
    border-radius: 3px;
    border-left: 2px solid var(--abyssal-teal);
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.npc-ability-inner {
    display: flex;
    align-items: center;
    gap: 6px;
    flex: 1;
}

.npc-ability-name {
    color: var(--abyssal-teal);
    font-size: 0.8em;
    min-width: 28px;
    font-weight: 600;
}

.npc-ability-score {
    font-size: 0.8em;
    font-weight: 600;
    color: var(--abyssal-light);
    min-width: 22px;
    text-align: right;
}

.npc-ability-modifier {
    font-size: 0.75em;
    color: var(--abyssal-glow);
    font-weight: 600;
    min-width: 28px;
    text-align: right;
    margin-left: auto;
}

/* ==========================================================================
   Saving Throws
   ========================================================================== */

.npc-saves-container {
    background: rgba(27, 42, 106, 0.3);
    border-radius: 8px;
    border: 2px solid var(--abyssal-glow);
    padding: 10px;
    display: flex;
    flex-direction: column;
    height: 100%;
    width: 100%;
}

.npc-saves-title {
    color: var(--abyssal-glow);
    font-size: 0.9em;
    display: block;
    margin-bottom: 8px;
    flex: 0 0 auto;
    font-weight: 600;
}

.npc-saves-list {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: space-around;
}

.npc-save-row {
    padding: 4px 8px;
    background: rgba(27, 42, 106, 0.4);
    border-radius: 3px;
    border-left: 2px solid var(--abyssal-teal);
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.npc-save-name {
    font-size: 0.8em;
    color: var(--abyssal-light);
}

.npc-save-value {
    font-size: 0.8em;
    color: var(--abyssal-glow);
    font-weight: 600;
    min-width: 30px;
    text-align: right;
}

/* ==========================================================================
   Level/CR Display
   ========================================================================== */

.npc-level-panel {
    padding: 6px 10px;
    background: rgba(27, 42, 106, 0.5);
    border-radius: 4px;
    border-bottom: 2px solid var(--abyssal-glow);
    margin-bottom: 6px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex: 0 0 auto;
}

.npc-level-label {
    color: var(--abyssal-glow);
    font-size: 0.85em;
    font-weight: 600;
}

.npc-level-value {
    font-size: 1em;
    font-weight: 600;
    color: var(--abyssal-light);
}

.npc-cr-panel {
    padding: 6px 10px;
    background: rgba(27, 42, 106, 0.5);
    border-radius: 4px;
    border-bottom: 2px solid var(--abyssal-glow);
    margin-bottom: 6px;
    flex: 0 0 auto;
}

.npc-cr-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.npc-cr-row + .npc-cr-row {
    margin-top: 4px;
}

.npc-cr-label {
    color: var(--abyssal-glow);
    font-size: 0.85em;
    font-weight: 600;
}

.npc-cr-value {
    font-size: 1em;
    font-weight: 600;
    color: var(--abyssal-light);
}

.npc-xp-label {
    color: var(--abyssal-light);
    font-size: 0.75em;
}

.npc-xp-value {
    font-size: 0.8em;
    font-weight: 600;
    color: var(--abyssal-teal);
}

/* Race and Class Info */
.npc-info-row {
    padding: 5px 8px;
    background: rgba(27, 42, 106, 0.4);
    border-radius: 3px;
    border-left: 2px solid var(--abyssal-glow);
    margin-bottom: 4px;
    flex: 0 0 auto;
}

.npc-info-label {
    color: var(--abyssal-glow);
    display: block;
    font-size: 0.7em;
    margin-bottom: 2px;
    font-weight: 600;
}

.npc-info-value {
    font-size: 0.8em;
    color: var(--abyssal-light);
}

/* ==========================================================================
   Inventory Items
   ========================================================================== */

.npc-inventory-item {
    background: rgba(27, 42, 106, 0.3);
    padding: 12px;
    border-radius: 4px;
    position: relative;
    transition: all 0.2s;
}

.npc-inventory-item:hover {
    background: rgba(27, 42, 106, 0.6);
}

.npc-inventory-item--weapon {
    border-left: 3px solid var(--abyssal-teal);
}

.npc-inventory-item--item {
    border-left: 3px solid var(--abyssal-glow);
}

.npc-inventory-item--equipped {
    background: rgba(27, 42, 106, 0.5);
    border-left: 4px solid var(--abyssal-teal);
    box-shadow: 0 0 10px rgba(20, 184, 166, 0.4);
}

.npc-inventory-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: 8px;
}

.npc-inventory-image {
    width: 60px;
    height: 60px;
    object-fit: cover;
    border-radius: 4px;
    margin-right: 12px;
    flex-shrink: 0;
}

.npc-inventory-image--weapon {
    border: 2px solid var(--abyssal-teal);
}

.npc-inventory-image--item {
    border: 2px solid var(--abyssal-glow);
}

.npc-inventory-name {
    cursor: pointer;
    text-decoration: underline;
    text-decoration-thickness: 2px;
    text-underline-offset: 3px;
    font-weight: 600;
    font-size: 1.1em;
}

.npc-inventory-name:hover {
    opacity: 0.7;
}

.npc-inventory-name--weapon {
    color: var(--abyssal-teal);
    text-decoration-color: var(--abyssal-teal);
}

.npc-inventory-name--item {
    color: var(--abyssal-glow);
    text-decoration-color: var(--abyssal-glow);
}

.npc-inventory-damage {
    margin-top: 4px;
    font-size: 0.85em;
    color: var(--abyssal-light);
}

.npc-inventory-weight {
    text-align: right;
    font-size: 0.9em;
    color: var(--abyssal-light);
}

.npc-inventory-description {
    margin-top: 8px;
    font-size: 0.9em;
    color: var(--abyssal-light);
    line-height: 1.5;
}

.npc-inventory-actions {
    display: flex;
    align-items: center;
    gap: 10px;
}

.npc-quantity-display {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-left: 6px;
    font-size: 0.85em;
}

.npc-quantity-value {
    min-width: 25px;
    text-align: center;
}

/* ==========================================================================
   Feature Cards
   ========================================================================== */

.npc-feature-card {
    background: rgba(27, 42, 106, 0.3);
    padding: 12px;
    border-radius: 4px;
    border-left: 3px solid var(--abyssal-glow);
    transition: all 0.2s;
}

.npc-feature-card:hover {
    background: rgba(27, 42, 106, 0.5);
}

.npc-feature-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: 8px;
}

.npc-feature-name {
    color: var(--abyssal-glow);
    font-weight: 600;
    font-size: 1.1em;
}

.npc-feature-type {
    font-size: 0.75em;
    color: var(--abyssal-light);
    opacity: 0.7;
    text-transform: uppercase;
}

.npc-feature-description {
    font-size: 0.9em;
    color: var(--abyssal-light);
    line-height: 1.5;
}

.npc-feature-uses {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 8px;
}

.npc-feature-use-btn {
    padding: 4px 8px;
    background: rgba(168, 85, 247, 0.2);
    border: 1px solid var(--abyssal-glow);
    border-radius: 4px;
    color: var(--abyssal-glow);
    cursor: pointer;
    font-size: 0.75em;
    font-weight: 600;
    transition: all 0.2s;
}

.npc-feature-use-btn:hover {
    background: rgba(168, 85, 247, 0.4);
}

.npc-feature-uses-display {
    color: var(--abyssal-teal);
    font-weight: 600;
    font-size: 0.85em;
}

.npc-feature-actions {
    display: flex;
    gap: 8px;
}

/* ==========================================================================
   Utility Classes
   ========================================================================== */

.npc-empty-state {
    grid-column: 1/-1;
    text-align: center;
    padding: 40px;
    color: var(--abyssal-light);
    opacity: 0.6;
}

.npc-loading-state {
    text-align: center;
    padding: 40px;
    color: var(--abyssal-light);
    opacity: 0.6;
}

.npc-help-icon {
    font-size: 0.85em;
    opacity: 0.7;
}

/* ==========================================================================
   Responsive Adjustments
   ========================================================================== */

@media (max-width: 768px) {
    .npc-inventory-header {
        flex-direction: column;
    }

    .npc-inventory-image {
        margin-right: 0;
        margin-bottom: 8px;
    }

    .npc-inventory-actions {
        flex-wrap: wrap;
    }
}


/* pages/_character-level-up-wizard.css */
/**
 * Character Level Up Wizard Styles
 * Uses existing modal, button, and form styles - only adds layout-specific rules
 */

/* Wizard Modal - uses existing .modal styles */
.level-up-wizard-modal {
    z-index: 10000;
}

.level-up-wizard-content {
    max-width: 700px;
    width: 90%;
    max-height: 90vh;
    display: flex;
    flex-direction: column;
    padding: 0;
}

/* Wizard Header - uses existing .modal-header styles */
.level-up-wizard-header {
    padding: 20px 25px;
    border-bottom: 2px solid color-mix(in srgb, var(--primary-color) 30%, transparent);
}

.level-up-wizard-header-left {
    display: flex;
    flex-direction: column;
    gap: 8px;
    flex: 1;
}

/* Progress Indicator */
.wizard-progress {
    position: relative;
    width: 100%;
    height: 24px;
    background: color-mix(in srgb, var(--theme-color-2) 30%, transparent);
    border-radius: 12px;
    overflow: hidden;
    border: 1px solid color-mix(in srgb, var(--primary-color) 20%, transparent);
}

.wizard-progress-bar {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    background: linear-gradient(90deg, 
        var(--primary-color) 0%, 
        var(--secondary-color) 100%);
    transition: width 0.3s ease;
    border-radius: 12px;
}

.wizard-progress-text {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: 0.75em;
    font-weight: 600;
    color: var(--text-light);
    z-index: 1;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
}

.level-up-wizard-close {
    background: transparent;
    border: none;
    color: var(--text-light);
    font-size: 2em;
    cursor: pointer;
    padding: 0;
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 4px;
    transition: all 0.2s ease;
}

.level-up-wizard-close:hover {
    background: color-mix(in srgb, var(--primary-color) 20%, transparent);
    color: var(--primary-color);
}

/* Wizard Body */
.level-up-wizard-body {
    flex: 1;
    overflow-y: auto;
    padding: 25px;
    min-height: 0;
}

/* Wizard Steps - uses existing modal-content styles */
.wizard-step {
    animation: fadeIn 0.3s ease;
}

@keyframes fadeIn {
    from {
        opacity: 0;
        transform: translateY(10px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* Step 1: Overview - uses existing form-group styles */
.level-display {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 20px;
    margin: 20px 0;
    padding: 20px;
}

.level-current,
.level-target {
    font-size: 2em;
    font-weight: 700;
}

.level-arrow {
    font-size: 1.5em;
}

.character-info {
    margin: 20px 0;
}

.character-info p {
    margin: 8px 0;
}

.progression-preview {
    margin: 20px 0;
    border-left: 4px solid var(--secondary-color);
}

.progression-preview h4 {
    margin: 0 0 10px 0;
}

.progression-preview ul {
    margin: 0;
    padding-left: 20px;
}

.progression-preview li {
    margin: 8px 0;
}

.progression-warning {
    margin: 20px 0;
    border-left: 4px solid #ff8844;
}

/* Step 2: Features - uses existing form-group styles */
.features-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-top: 15px;
}

.feature-item {
    transition: all 0.2s ease;
}

.feature-checkbox {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    cursor: pointer;
}

.feature-checkbox input[type="checkbox"] {
    margin-top: 4px;
    cursor: pointer;
}

.feature-info {
    flex: 1;
}

.feature-name {
    font-weight: 600;
    margin-bottom: 6px;
}

.feature-description {
    font-size: 0.9em;
    opacity: 0.9;
    line-height: 1.5;
}

/* Step 3: Ability Scores - uses existing form-group styles */
.ability-scores-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 12px;
    margin: 20px 0;
}

.ability-score-item {
    padding: 15px;
    text-align: center;
}

.ability-score-name {
    font-weight: 600;
    margin-bottom: 10px;
    text-transform: uppercase;
    font-size: 0.9em;
}

.ability-score-display {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    margin: 10px 0;
    font-size: 1.2em;
}

.ability-score-arrow {
    opacity: 0.6;
}

.ability-score-new {
    font-weight: 700;
}

.ability-score-controls {
    display: flex;
    gap: 8px;
    justify-content: center;
    margin-top: 10px;
}

.asi-summary {
    margin-top: 20px;
    text-align: center;
}

/* Step 4: Spell Slots - uses existing form-group styles */
.spell-slots-update,
.proficiency-bonus-update {
    margin: 20px 0;
}

.spell-slots-update h4,
.proficiency-bonus-update h4 {
    margin: 0 0 12px 0;
}

.spell-slots-comparison {
    display: flex;
    align-items: center;
    gap: 15px;
    flex-wrap: wrap;
}

.spell-slots-current,
.spell-slots-new {
    flex: 1;
    min-width: 200px;
}

.spell-slots-arrow {
    opacity: 0.6;
    font-size: 1.2em;
}

.proficiency-bonus-comparison {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 15px;
    font-size: 1.5em;
}

.proficiency-bonus-arrow {
    opacity: 0.6;
}

.proficiency-bonus-new {
    font-weight: 700;
}

/* Step 5: HP & Hit Dice - uses existing form-group styles */
.hp-increase-section,
.hit-dice-increase-section {
    margin: 20px 0;
}

.hp-increase-section h4,
.hit-dice-increase-section h4 {
    margin: 0 0 12px 0;
}

.hp-increase-options {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
    margin: 15px 0;
}

.hp-manual-input {
    flex: 1;
    min-width: 120px;
}

.hp-increase-result {
    margin-top: 15px;
}

.hit-dice-info {
    margin-top: 10px;
}

/* Step 6: Summary - uses existing form-group styles */
.summary-section {
    margin: 20px 0;
    border-left: 4px solid var(--primary-color);
}

.summary-section h4 {
    margin: 0 0 10px 0;
}

.summary-section ul {
    margin: 10px 0;
    padding-left: 20px;
}

.summary-section li {
    margin: 6px 0;
}

/* Wizard Footer - uses existing .modal-actions styles */
.level-up-wizard-footer {
    padding: 20px 25px;
    border-top: 2px solid color-mix(in srgb, var(--primary-color) 30%, transparent);
}

.wizard-footer-buttons {
    display: flex;
    gap: 12px;
    justify-content: flex-end;
}

/* Scrollbar - uses existing modal scrollbar styles */

/* Responsive */
@media (max-width: 768px) {
    .level-up-wizard-content {
        max-width: 95%;
        max-height: 95vh;
    }
    
    .level-up-wizard-header {
        padding: 15px 20px;
    }
    
    .level-up-wizard-body {
        padding: 20px 15px;
    }
    
    .level-up-wizard-footer {
        padding: 15px 20px;
    }
    
    .wizard-footer-buttons {
        flex-direction: column;
    }
    
    .wizard-footer-buttons .btn {
        width: 100%;
    }
    
    .ability-scores-grid {
        grid-template-columns: 1fr;
    }
    
    .hp-increase-options {
        flex-direction: column;
    }
    
    .hp-manual-input {
        width: 100%;
    }
}



/* pages/_detail-tabs.css */
/**
 * Detail Tabs Styles
 * Tab navigation for character and NPC detail pages
 */

/* Detail Tab Container */
.detail-tab-container {
    display: flex;
    gap: 8px;
    border-bottom: 2px solid color-mix(in srgb, var(--secondary-color, var(--abyssal-teal)) 30%, transparent);
    margin-bottom: 20px;
}

/* Detail Tab Buttons */
.detail-tab-btn {
    padding: 10px 20px;
    background: color-mix(in srgb, var(--theme-color-1, var(--abyssal-purple, #154772)) 10%, transparent);
    border: none;
    border-bottom: 2px solid transparent;
    color: var(--text-light, var(--abyssal-light, #ffffff));
    cursor: pointer;
    font-weight: 600;
    border-radius: 4px 4px 0 0;
    transition: all 0.2s;
}

.detail-tab-btn.active {
    background: color-mix(in srgb, var(--theme-color-1, var(--abyssal-purple, #154772)) 20%, transparent);
    border-bottom: 2px solid var(--theme-color-3, var(--abyssal-glow, #4DD0E1));
    color: var(--theme-color-3, var(--abyssal-glow, #4DD0E1));
}

/* Detail Tab Content */
.detail-tab-content {
    display: none;
}

.detail-tab-content.active {
    display: block;
}


/* pages/_geography.css */
/**
 * Geography & Maps Pages - Unique Layout Styles
 * These pages use form-list card styles but have unique list layouts
 * Cards are shared via pages/_form-list-pages.css
 */

.geography-page .world-header {
    background: var(--panel-75);
    padding: 25px;
    border-radius: 12px;
    border: 2px solid color-mix(in srgb, var(--primary-color) 45%, transparent);
    margin-bottom: 30px;
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    backdrop-filter: blur(10px);
    gap: 20px;
}

.geography-page .world-info {
    flex: 1;
}

.geography-page .world-header h2 {
    color: var(--primary-color);
    font-size: 2em;
    margin: 0;
    text-shadow: 0 0 12px color-mix(in srgb, var(--primary-color) 45%, transparent);
}

.geography-page .controls {
    margin: 20px 0;
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.geography-page .controls .button-group {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
}

.geography-page .world-actions {
    display: flex;
    gap: 10px;
    flex-wrap: wrap;
    justify-content: flex-end;
}

.geography-page #worldDescription {
    color: var(--text-light);
    margin-top: 15px;
    line-height: 1.6;
}

.geography-page .currency-tier-card {
    padding: 18px;
    background: var(--panel-60);
    border-radius: 10px;
    border-left: 3px solid color-mix(in srgb, var(--secondary-color) 55%, transparent);
    box-shadow: 0 10px 25px color-mix(in srgb, var(--shadow-color) 25%, transparent);
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.geography-page .currency-tier-card .field-row {
    gap: 18px;
}

.geography-page .currency-tier-card input,
.geography-page .currency-tier-card select,
.geography-page .currency-tier-card textarea {
    width: 100%;
}

.geography-page .currency-tier-card .form-switch {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 0.9rem;
    color: var(--text-light);
    cursor: pointer;
}

.geography-page .currency-tier-card .form-switch input[type="checkbox"] {
    accent-color: var(--secondary-color);
}

.geography-page .currency-tier-card .actions-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    margin-top: 12px;
}

.geography-page .currency-base-display {
    background: color-mix(in srgb, var(--panel-40) 60%, transparent);
    border-style: dashed;
    color: var(--text-dim);
    font-style: italic;
}

.geography-page .currency-intro {
    margin-bottom: 20px;
    padding: 15px;
    background: color-mix(in srgb, var(--panel-40) 65%, transparent);
    border-radius: 8px;
}

.geography-page .currency-intro p {
    font-size: 0.9em;
}

.geography-page .currency-empty {
    text-align: center;
    padding: 24px;
    border-radius: 10px;
    background: var(--panel-60);
    color: var(--text-dim);
}

.geography-page .preview-placeholder {
    padding: 10px;
}

.geography-page .preview-image {
    max-width: 100%;
    max-height: 200px;
    border-radius: 6px;
}

.geography-page .btn-full-width {
    width: 100%;
    margin-top: 15px;
}

.geography-page .modal-inline-actions {
    display: flex;
    gap: 10px;
    margin-top: 20px;
}

.geography-page .modal-inline-actions .btn {
    flex: 1;
}

.geography-page .image-preview-container {
    margin-top: 10px;
}

.geography-page .image-placeholder {
    padding: 20px;
    color: var(--text-light);
    opacity: 0.5;
}

/* Geography page unique list layout (full-width vs grid) */
.geography-page .item-grid,
.pantheon-page .item-grid {
    display: block;
    width: 100%;
    margin-top: 12px;
}

/* Geography page detail modal - unique structure */
.geography-page .detail-modal {
    display: none;
    position: fixed;
    z-index: 2000;
    left: 0 !important; /* Full screen, ignore page padding */
    top: 0 !important; /* Full screen, ignore page padding */
    width: 100vw !important; /* Full viewport width */
    height: 100vh !important; /* Full viewport height */
    background: color-mix(in srgb, var(--shadow-color) 65%, transparent);
    backdrop-filter: blur(6px);
    /* Modal is full-screen overlay, not affected by page padding or sidebar */
    padding: 0 !important;
    margin: 0 !important;
    box-sizing: border-box;
}

.geography-page .detail-modal.show {
    display: flex;
    align-items: center;
    justify-content: center;
}

.geography-page .detail-modal-content {
    background: var(--panel-90);
    border: 2px solid color-mix(in srgb, var(--primary-color) 45%, transparent);
    border-radius: 12px;
    padding: 30px;
    max-width: 900px;
    width: 90%;
    max-height: 85vh;
    overflow-y: auto;
    position: relative;
    box-shadow: 0 20px 60px color-mix(in srgb, var(--shadow-color) 50%, transparent);
}

.geography-page .detail-modal-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: 20px;
    padding-bottom: 15px;
    border-bottom: 2px solid color-mix(in srgb, var(--primary-color) 35%, transparent);
}

.geography-page .detail-modal-title {
    color: var(--primary-color);
    font-size: 2em;
    font-weight: 600;
    margin: 0;
}

.geography-page .detail-modal-close {
    background: var(--accent-accent-20);
    border: 1px solid var(--accent-color);
    color: var(--accent-color);
    border-radius: 50%;
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    font-size: 1.5em;
    transition: all 0.2s ease;
}

.geography-page .detail-modal-close:hover {
    background: var(--accent-accent-35);
}

.geography-page .detail-meta {
    margin-top: 8px;
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.geography-page .detail-parent {
    font-size: 0.9em;
}

.geography-page .detail-image {
    width: 100%;
    max-height: 700px;
    object-fit: contain;
    border-radius: 8px;
    margin-bottom: 15px;
}

.geography-page .detail-body {
    margin-top: 15px;
}

.geography-page .detail-description {
    color: var(--text-light);
    line-height: 1.6;
    margin-top: 10px;
}

.geography-page .detail-description.is-empty {
    font-style: italic;
    opacity: 0.5;
}

.geography-page .detail-actions {
    margin-top: 20px;
    display: flex;
    gap: 10px;
    justify-content: flex-end;
}

/* Geography page child location styles */
.geography-page .detail-child-name {
    color: var(--primary-color);
    font-weight: 600;
}

.geography-page .detail-child-type {
    color: var(--text-light);
}

.geography-page .detail-child-summary {
    color: var(--text-light);
    opacity: 0.8;
    font-size: 0.9em;
}

.geography-page .detail-section {
    margin-bottom: 15px;
}

.geography-page .detail-section h3 {
    color: var(--primary-color);
    margin-bottom: 8px;
    font-size: 1.1em;
}

.geography-page .detail-children {
    margin-top: 15px;
    padding-left: 20px;
}

.geography-page .detail-child-card {
    background: var(--panel-40);
    border: 1px solid var(--panel-60);
    border-radius: 6px;
    padding: 10px;
    margin-bottom: 8px;
}

.geography-page .detail-child-card:hover {
    background: var(--panel-60);
}

.geography-page .world-card {
    background: var(--panel-75);
    border: 2px solid color-mix(in srgb, var(--primary-color) 45%, transparent);
    border-radius: 12px;
    padding: 20px;
    margin-bottom: 20px;
}

.geography-page .world-card.has-locations {
    border-color: var(--primary-color);
}

.geography-page .world-card .item-header {
    margin-bottom: 15px;
}

.geography-page .item-card .item-header {
    margin-bottom: 8px;
}

.geography-page .location-meta {
    display: flex;
    gap: 12px;
    font-size: 0.85em;
}

.geography-page .location-count {
    color: var(--primary-color);
}

.geography-page .location-summary {
    color: var(--text-light);
    opacity: 0.7;
    font-size: 0.9em;
    margin-top: 8px;
}

.geography-page .location-name-lg {
    font-size: 1.3em;
}

.geography-page .location-card {
    background: var(--panel-60);
    border-radius: 8px;
    padding: 12px;
}

.geography-page .location-card-details {
    margin-top: 10px;
}

.geography-page .location-card-details.has-children {
    border-left: 3px solid var(--primary-color);
    padding-left: 15px;
}

.geography-page .location-image {
    width: 100%;
    max-height: 200px;
    object-fit: cover;
    border-radius: 6px;
    margin-bottom: 10px;
}

.geography-page .location-empty {
    padding: 20px;
    text-align: center;
    color: var(--text-light);
    opacity: 0.6;
}

.geography-page .expand-toggle-wrapper {
    display: flex;
    justify-content: flex-end;
    margin-top: 8px;
}

.geography-page .expand-toggle {
    padding: 4px 8px;
    background: var(--accent-primary-20);
    border: 1px solid var(--primary-color);
    border-radius: 4px;
    color: var(--primary-color);
    cursor: pointer;
    font-size: 0.85em;
}

.geography-page .expand-toggle:hover {
    background: var(--accent-primary-35);
}

.geography-page .location-children-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
    gap: 12px;
    margin-top: 12px;
    padding-left: 20px;
}

.geography-page .location-children-grid.collapsed {
    display: none;
}

.geography-page .item-card.has-children {
    border-left-width: 4px;
}

.geography-page .item-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: 8px;
    gap: 10px;
}

.geography-page .item-header > div:first-child {
    flex: 1;
    min-width: 0;
}

.geography-page .item-header > div > div {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
}

.geography-page .location-name {
    color: var(--primary-color);
    font-weight: 600;
    font-size: 1.1em;
}

/* Maps Page Image Viewer Modal */
.maps-page .image-viewer-modal {
    display: none;
    position: fixed;
    z-index: 2000;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background-color: color-mix(in srgb, var(--shadow-color) 90%, transparent);
    cursor: zoom-out;
}

.maps-page .image-viewer-modal.show {
    display: flex;
    align-items: center;
    justify-content: center;
}

.maps-page .image-viewer-modal img {
    max-width: 95%;
    max-height: 95%;
    object-fit: contain;
    border: 3px solid var(--secondary-color);
    border-radius: 8px;
}

.maps-page .image-viewer-modal .image-report-button {
    position: absolute;
    top: 16px;
    right: 16px;
    padding: 9px 14px;
    border: 1px solid var(--border-color);
    border-radius: 6px;
    background: var(--surface-panel);
    color: var(--text-light);
    cursor: pointer;
}


/* pages/_quests.css */
/**
 * Quest log (`S-92`)
 *
 * The list itself comes from the shared .form-list-item rules in
 * _cards.css — only what is particular to a quest is here: which of the four
 * states it is in, and its objectives.
 */

.quest-filter-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 12px;
}

.quest-filter {
    background: transparent;
    border: 1px solid var(--border-color);
    color: var(--text-dim);
}

.quest-filter.is-active {
    border-color: var(--primary-color);
    color: var(--primary-color);
}

/*
 * The status is carried by the item's left border as well as the badge, so a
 * long log can be read down its edge. Completed and failed are dimmed rather
 * than hidden: what the party has already done is part of the log.
 */
.quest-item.quest-active {
    border-left-color: var(--primary-color);
}

.quest-item.quest-rumour {
    border-left-color: var(--text-dim);
}

.quest-item.quest-completed,
.quest-item.quest-failed {
    opacity: 0.7;
}

.quest-item.quest-completed {
    border-left-color: var(--secondary-color);
}

/*
 * A failed quest is a state, not an error, so it takes the theme's own accent
 * rather than the fixed error red. Errors stay unthemed on purpose; this is
 * not one.
 */
.quest-item.quest-failed {
    border-left-color: var(--accent-color, var(--text-dim));
}

.quest-status-badge {
    display: inline-block;
    margin-left: 8px;
    padding: 1px 8px;
    border-radius: 10px;
    border: 1px solid var(--border-color);
    font-size: 0.75em;
    color: var(--text-dim);
    vertical-align: middle;
}

.quest-objectives {
    list-style: none;
    margin: 8px 0 0;
    padding: 0;
}

.quest-objectives li {
    margin: 2px 0;
    font-size: 0.9em;
}

.quest-objectives label {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
}

.quest-objective-done {
    text-decoration: line-through;
    opacity: 0.6;
}

/* A viewer reads the log; only whoever runs the campaign ticks it off. */
body.viewer-mode .quest-objectives input[type="checkbox"] {
    pointer-events: none;
    opacity: 0.5;
}

/*
 * Rewards that are real items.
 *
 * The quest stores a reference, so a chip is a link to that item's own card
 * rather than a copy of its stats.
 */
.reward-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 6px;
}

.reward-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 2px 10px;
    border: 1px solid var(--border-color);
    border-radius: 12px;
    font-size: 0.8em;
    color: var(--primary-color);
    text-decoration: none;
}

a.reward-chip:hover {
    border-color: var(--primary-color);
    text-decoration: underline;
}

.reward-chip-remove {
    background: none;
    border: none;
    padding: 0;
    color: var(--text-dim);
    cursor: pointer;
    font-size: 1.1em;
    line-height: 1;
}

.reward-chip-remove:hover {
    color: var(--primary-color);
}

.reward-item-results {
    margin-top: 4px;
}

.reward-item-option {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    width: 100%;
    padding: 6px 10px;
    background: transparent;
    border: 1px solid var(--border-color);
    border-radius: 4px;
    margin-bottom: 4px;
    color: var(--text-light);
    text-align: left;
    cursor: pointer;
}

.reward-item-option:hover {
    border-color: var(--primary-color);
}

.reward-item-empty {
    padding: 6px 10px;
    color: var(--text-dim);
    font-size: 0.85em;
}


/* pages/_rules.css */
/**
 * Campaign rules documents (`S-90`)
 *
 * A document, not a list — read top to bottom at the table, so it takes a
 * reading measure and a contents list rather than the card grid the data
 * pages use.
 */

.rules-document {
    max-width: 70ch;
}

.rules-contents-list {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 16px;
    margin-bottom: 16px;
    padding: 10px 12px;
    border: 1px solid var(--border-color);
    border-radius: 6px;
    background: var(--panel-75);
}

.rules-contents-list a {
    color: var(--primary-color);
    font-size: 0.9em;
    text-decoration: none;
}

.rules-contents-list a:hover {
    text-decoration: underline;
}

.rules-section {
    padding: 12px 0 16px;
    border-bottom: 1px solid var(--border-color);
}

.rules-section:last-child {
    border-bottom: none;
}

.rules-section-header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
}

.rules-section-header h2 {
    margin: 0;
    color: var(--primary-color);
    font-size: 1.15em;
}

/*
 * The rule as it was typed: paragraph breaks are how someone writing a rule
 * separates one clause from the next, so the body keeps a comfortable line
 * length and honest spacing.
 */
.rules-section-body {
    margin-top: 8px;
    color: var(--text-light);
    line-height: 1.6;
}

/* A reader is not an editor. The controls go, the document stays. */
body.viewer-mode .rules-section-header .form-list-item-actions {
    display: none;
}


/* pages/_damage-defences.css */
/**
 * What a creature shrugs off.
 *
 * A row that adds one defence, and a chip for each one set — so the space
 * this takes is proportional to what a creature actually resists, not to how
 * many kinds of damage the campaign has. The first version drew all thirteen
 * types with four radios each: a hundred and four controls to say "immune to
 * fire".
 */

.damage-defence-add {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    align-items: center;
}

.damage-defence-type {
    flex: 1 1 120px;
    min-width: 0;
}

.damage-defence-state {
    flex: 2 1 180px;
    min-width: 0;
}

.damage-defence-chips {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin-top: 8px;
}

.damage-defence-group {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
}

.damage-defence-label {
    font-size: 0.75em;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    opacity: 0.85;
    min-width: 72px;
}

.damage-defence-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 1px 8px;
    border: 1px solid currentColor;
    border-radius: 12px;
    font-size: 0.8em;
}

/*
 * Three states, three readings. Immune is the strongest claim and reads
 * strongest; vulnerable is the one that hurts and takes the warning colour.
 * These are meanings rather than decoration, so they are named from the
 * theme's own roles rather than picked as raw colours.
 */
.damage-defence-immune {
    color: var(--primary-color);
}

.damage-defence-resistant {
    color: var(--secondary-color, var(--abyssal-teal));
}

.damage-defence-vulnerable {
    color: var(--accent-color, var(--abyssal-accent));
}

.damage-defence-remove {
    background: none;
    border: none;
    padding: 0;
    color: inherit;
    opacity: 0.7;
    cursor: pointer;
    font-size: 1.1em;
    line-height: 1;
}

.damage-defence-remove:hover {
    opacity: 1;
}

.damage-defence-none {
    color: var(--text-dim);
    font-size: 0.85em;
}

/* A reader is not an editor. */
body.viewer-mode .damage-defence-add,
body.viewer-mode .damage-defence-remove {
    display: none;
}


/* pages/_notes.css */
/**
 * Notes Page Styles
 * Simple notes page with editable fields
 */

.notes-page .section {
    margin: 30px 0;
    padding: 20px;
    background: var(--panel-75);
    border-radius: 8px;
    border-left: 4px solid var(--primary-color);
    backdrop-filter: blur(10px);
}

.notes-page h2 {
    color: var(--secondary-color);
    margin-bottom: 15px;
}

/* The campaign home page uses the same editable field, and was never included
   here — so its World Setting and Session Notes boxes got none of this and fell
   back to the browser's default textarea: two rows, 187px wide, holding a
   396-character setting description you could see one line of at a time. */
.notes-page .editable-field,
.home-page .editable-field {
    position: relative;
    margin-top: 20px;
}

.notes-page .editable-field textarea,
.home-page .editable-field textarea {
    width: 100%;
    min-height: 400px;
    padding: 15px;
    background: var(--panel-60);
    border: 2px solid var(--primary-color);
    border-radius: 8px;
    color: var(--text-light);
    font-family: 'Courier New', monospace;
    font-size: 1em;
    line-height: 1.6;
    resize: vertical;
    transition: border-color 0.3s ease, box-shadow 0.3s ease;
}

/* Home holds two of these on one page and is not the place you settle in to
   write, so they start shorter — still a box you can compose a paragraph in,
   and draggable when you want more. */
.home-page .editable-field textarea {
    min-height: 160px;
}

.notes-page .editable-field textarea:focus,
.home-page .editable-field textarea:focus {
    outline: none;
    border-color: var(--accent-color);
    box-shadow: 0 0 15px var(--shadow-primary-25);
}

.notes-page .save-btn,
.home-page .save-btn {
    margin-top: 10px;
    padding: 10px 20px;
    background: linear-gradient(135deg, var(--primary-color), var(--accent-color));
    border: none;
    border-radius: 6px;
    color: var(--text-light);
    font-size: 1em;
    font-weight: 600;
    cursor: pointer;
    transition: transform 0.2s ease, box-shadow 0.2s ease;
}

.notes-page .save-btn:hover,
.home-page .save-btn:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 15px var(--shadow-primary-35);
}

/* The button and its "Saved!" were touching. */
.home-page .field-actions {
    display: flex;
    align-items: center;
    gap: 12px;
}

/* ============================================
   The campaign overview cards
   ============================================ */

.home-page .overview-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: 16px;
    margin-bottom: 24px;
}

.home-page .overview-card {
    display: flex;
    flex-direction: column;
    gap: 8px;
    background: var(--panel-60);
    border: 1px solid var(--abyssal-glow);
    border-radius: 10px;
    padding: 16px;
}

.home-page .overview-card-title {
    margin: 0;
    font-size: 0.78rem;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--abyssal-light);
    opacity: 0.7;
}

.home-page .overview-card-body {
    color: var(--text-light);
    font-size: 0.9rem;
}

.home-page .overview-strong {
    margin: 0;
    font-size: 1.4rem;
    font-weight: 700;
    color: var(--abyssal-glow);
}

.home-page .overview-sub {
    margin: 2px 0 0;
    opacity: 0.8;
}

.home-page .overview-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 5px;
}

.home-page .overview-list li {
    display: flex;
    justify-content: space-between;
    gap: 10px;
    align-items: baseline;
}

.home-page .overview-list-who {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.home-page .overview-list-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Who is playing this character. */
.home-page .overview-list-owner {
    font-size: 0.72rem;
    opacity: 0.6;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* A character nobody has claimed is a seat still going spare, which is worth
   noticing rather than reading as just another name. */
.home-page .overview-list-owner.is-unclaimed {
    font-style: italic;
    opacity: 0.45;
}

.home-page .overview-list-detail {
    flex-shrink: 0;
    font-size: 0.78rem;
    opacity: 0.65;
}

/* Somebody on their last legs is the one thing on this page worth
   interrupting you for. */
.home-page .overview-list li.is-hurt .overview-list-detail {
    color: var(--danger-color);
    opacity: 1;
}

.home-page .overview-list-more {
    font-size: 0.78rem;
    opacity: 0.55;
}

/* ============================================
   The session journal
   ============================================ */

/* A run of entries in the order they happened, with the box to add the next
   one underneath — the shape of a chat log rather than a document, because
   that is what a session journal is: things that happened, in order, each
   with a date on it. */
/* Room to grow, from the first note.
   A campaign accumulates these for as long as it is played, so a box sized to
   whatever is in it today is a box that spends the rest of its life scrolling.
   It starts tall and takes what the column gives it. */
.home-page .journal {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin: 16px 0;
    flex: 1;
    min-height: 420px;
    max-height: 65vh;
    overflow-y: auto;
}

.home-page .journal-entry {
    background: var(--panel-60);
    border: 1px solid var(--abyssal-glow);
    border-left-width: 3px;
    border-radius: 8px;
    padding: 12px 14px;
}

.home-page .journal-meta {
    font-size: 0.74rem;
    color: var(--abyssal-light);
    opacity: 0.65;
    margin-bottom: 6px;
}

.home-page .journal-text {
    margin: 0;
    color: var(--text-light);
    line-height: 1.55;
    /* Notes are typed with line breaks in them and they should keep them. */
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.home-page .journal-empty {
    margin: 16px 0;
    color: var(--abyssal-light);
    opacity: 0.6;
    font-style: italic;
}

.home-page .journal-compose textarea {
    width: 100%;
    min-height: 90px;
    padding: 12px;
    background: var(--panel-60);
    border: 2px solid var(--primary-color);
    border-radius: 8px;
    color: var(--text-light);
    font-family: inherit;
    font-size: 0.95em;
    line-height: 1.5;
    resize: vertical;
}

.home-page .journal-compose textarea:focus {
    outline: none;
    border-color: var(--accent-color);
    box-shadow: 0 0 15px var(--shadow-primary-25);
}


/* pages/_account-settings.css */
/**
 * Account Settings Page
 * Professional business page styling with dark mode support
 */

.account-settings-page {
    /* Background inherited from body element (already has theme-aware gradient) */
    min-height: 100vh;
    padding-top: 60px;
    transition: background 0.3s ease;
}

/* Ensure top banner displays properly */
.account-settings-page .top-banner {
    display: flex;
}

.settings-container {
    max-width: var(--page-max);
    margin: 0 auto;
    padding: 40px 24px;
}

.settings-header {
    margin-bottom: 32px;
}

.settings-header h1 {
    font-size: 28px;
    font-weight: 600;
    color: var(--text-light);
    margin: 0 0 8px 0;
    letter-spacing: -0.5px;
}

.settings-header p {
    font-size: 14px;
    color: var(--text-dim);
    margin: 0;
}

.settings-section {
    background: color-mix(in srgb, var(--panel-90) 85%, transparent 15%);
    backdrop-filter: blur(10px);
    border-radius: 8px;
    border: 1px solid color-mix(in srgb, var(--primary-color) 15%, transparent);
    margin-bottom: 24px;
    overflow: hidden;
    box-shadow: 0 4px 12px var(--shadow-ambient-30);
    transition: background 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
}

.section-header {
    padding: 20px 24px;
    border-bottom: 1px solid color-mix(in srgb, var(--primary-color) 15%, transparent);
    background: color-mix(in srgb, var(--panel-75) 80%, transparent 20%);
}

.section-header h2 {
    font-size: 16px;
    font-weight: 600;
    color: var(--text-light);
    margin: 0;
    letter-spacing: -0.2px;
}

.section-content {
    padding: 24px;
}

.info-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
    gap: 24px;
}

.info-item {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.info-label {
    font-size: 12px;
    font-weight: 500;
    color: var(--text-dim);
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.info-value {
    font-size: 15px;
    color: var(--text-light);
    font-weight: 500;
}

.badge {
    display: inline-flex;
    align-items: center;
    padding: 4px 12px;
    border-radius: 12px;
    font-size: 12px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.badge-free {
    background: color-mix(in srgb, var(--text-dim) 20%, transparent);
    color: var(--text-light);
}

.badge-premium {
    background: color-mix(in srgb, var(--primary-color) 25%, transparent);
    color: var(--primary-color);
}

.badge-pro {
    background: color-mix(in srgb, var(--accent-color) 25%, transparent);
    color: var(--accent-color);
}

.badge-active {
    background: color-mix(in srgb, var(--secondary-color) 25%, transparent);
    color: var(--secondary-color);
}

.badge-suspended {
    background: color-mix(in srgb, var(--accent-color) 20%, transparent);
    color: var(--accent-color);
}

.badge-cancelled {
    background: color-mix(in srgb, var(--danger-color) 20%, transparent);
    color: var(--danger-color);
}

.action-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 16px 0;
    border-bottom: 1px solid color-mix(in srgb, var(--primary-color) 8%, transparent);
    transition: background 0.2s ease;
}

.action-row:hover {
    background: color-mix(in srgb, var(--panel-40) 30%, transparent 70%);
    margin: 0 -24px;
    padding-left: 24px;
    padding-right: 24px;
    border-radius: 4px;
}

.action-row:last-child {
    border-bottom: none;
}

.action-info {
    flex: 1;
}

.action-title {
    font-size: 15px;
    font-weight: 500;
    color: var(--text-light);
    margin-bottom: 4px;
}

.action-description {
    font-size: 13px;
    color: var(--text-dim);
    margin: 0;
}

.btn-professional {
    padding: 8px 16px;
    font-size: 14px;
    font-weight: 500;
    border-radius: 6px;
    border: 1px solid color-mix(in srgb, var(--primary-color) 25%, transparent);
    background: color-mix(in srgb, var(--panel-75) 70%, transparent 30%);
    color: var(--text-light);
    cursor: pointer;
    transition: all 0.2s ease;
    backdrop-filter: blur(8px);
}

.btn-professional:hover {
    background: color-mix(in srgb, var(--panel-60) 80%, transparent 20%);
    border-color: color-mix(in srgb, var(--primary-color) 40%, transparent);
    transform: translateY(-1px);
    box-shadow: 0 2px 8px var(--shadow-primary-25);
}

.btn-primary-professional {
    background: var(--primary-color);
    color: var(--theme-color-2);
    border-color: var(--primary-color);
    box-shadow: 0 2px 8px var(--shadow-primary-25);
}

.btn-primary-professional:hover {
    background: color-mix(in srgb, var(--primary-color) 85%, var(--accent-color) 15%);
    border-color: color-mix(in srgb, var(--primary-color) 85%, var(--accent-color) 15%);
    box-shadow: 0 4px 12px var(--shadow-primary-35);
    transform: translateY(-1px);
}

.payment-card {
    background: color-mix(in srgb, var(--panel-90) 80%, transparent 20%);
    backdrop-filter: blur(8px);
    border: 1px solid color-mix(in srgb, var(--primary-color) 15%, transparent);
    border-radius: 8px;
    padding: 16px;
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 12px;
    transition: all 0.2s ease;
    box-shadow: 0 2px 6px var(--shadow-ambient-30);
}

.payment-card:hover {
    border-color: color-mix(in srgb, var(--primary-color) 30%, transparent);
    box-shadow: 0 4px 10px var(--shadow-ambient-40);
    transform: translateY(-1px);
}

.payment-card-info {
    display: flex;
    align-items: center;
    gap: 16px;
}

.payment-card-icon {
    width: 48px;
    height: 32px;
    background: linear-gradient(135deg, var(--primary-color) 0%, var(--accent-color) 100%);
    border-radius: 6px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--theme-color-2);
    font-size: 12px;
    font-weight: 600;
    box-shadow: 0 2px 6px var(--shadow-primary-25);
}

.payment-card-details h4 {
    font-size: 14px;
    font-weight: 600;
    color: var(--text-light);
    margin: 0 0 4px 0;
}

.payment-card-details p {
    font-size: 12px;
    color: var(--text-dim);
    margin: 0;
}

.payment-card-actions {
    display: flex;
    gap: 8px;
}

.billing-address-box {
    background: color-mix(in srgb, var(--panel-75) 75%, transparent 25%);
    backdrop-filter: blur(8px);
    border: 1px solid color-mix(in srgb, var(--primary-color) 15%, transparent);
    border-radius: 6px;
    padding: 16px;
    font-size: 14px;
    color: var(--text-light);
    line-height: 1.6;
}

.modal-professional {
    background: color-mix(in srgb, var(--theme-color-2) 70%, transparent 30%);
    backdrop-filter: blur(8px);
}

.modal-content-professional {
    position: relative;
    background: color-mix(in srgb, var(--panel-90) 90%, transparent 10%);
    backdrop-filter: blur(12px);
    border-radius: 8px;
    max-width: 500px;
    width: 90%;
    padding: 0;
    box-shadow: 0 20px 25px -5px var(--shadow-ambient-55), 0 0 0 1px color-mix(in srgb, var(--primary-color) 20%, transparent);
    border: 1px solid color-mix(in srgb, var(--primary-color) 25%, transparent);
}

.modal-header-professional {
    padding: 24px 24px 0 24px;
    border-bottom: 1px solid color-mix(in srgb, var(--primary-color) 20%, transparent);
    margin-bottom: 24px;
}

.modal-header-professional h2 {
    font-size: 20px;
    font-weight: 600;
    color: var(--text-light);
    margin: 0 0 24px 0;
}

.modal-body-professional {
    padding: 0 24px 24px 24px;
}

.form-group-professional {
    margin-bottom: 20px;
}

.form-group-professional label {
    display: block;
    font-size: 14px;
    font-weight: 500;
    color: var(--text-light);
    margin-bottom: 8px;
}

.form-group-professional input,
.form-group-professional select {
    width: 100%;
    padding: 10px 12px;
    font-size: 14px;
    border: 1px solid color-mix(in srgb, var(--primary-color) 25%, transparent);
    border-radius: 6px;
    background: color-mix(in srgb, var(--panel-75) 70%, transparent 30%);
    backdrop-filter: blur(6px);
    color: var(--text-light);
    transition: all 0.2s ease;
    box-sizing: border-box;
}

.form-group-professional input:focus,
.form-group-professional select:focus {
    outline: none;
    border-color: var(--primary-color);
    background: color-mix(in srgb, var(--panel-75) 85%, transparent 15%);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary-color) 20%, transparent), 0 2px 8px var(--shadow-primary-25);
}

.form-group-professional input::placeholder {
    color: var(--text-dim);
}

.form-group-professional.checkbox {
    display: flex;
    align-items: center;
    gap: 8px;
}

.form-group-professional.checkbox input {
    width: auto;
}

.form-group-professional.checkbox label {
    margin: 0;
    font-weight: 400;
}

.error-message-professional {
    background: color-mix(in srgb, var(--danger-color) 20%, transparent);
    border: 1px solid color-mix(in srgb, var(--danger-color) 40%, transparent);
    color: var(--danger-color);
    padding: 12px;
    border-radius: 6px;
    font-size: 14px;
    margin-bottom: 20px;
}

.modal-actions-professional {
    display: flex;
    gap: 12px;
    justify-content: flex-end;
    padding-top: 24px;
    border-top: 1px solid color-mix(in srgb, var(--primary-color) 20%, transparent);
}

.close-professional {
    position: absolute;
    top: 16px;
    right: 16px;
    font-size: 24px;
    font-weight: 300;
    color: var(--text-dim);
    cursor: pointer;
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 6px;
    transition: background 0.2s;
}

.close-professional:hover {
    background: var(--panel-60);
    color: var(--text-light);
}

/* Form Grid Layouts */
.form-grid-2 {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 16px;
}

.form-grid-2-1 {
    display: grid;
    grid-template-columns: 2fr 1fr;
    gap: 16px;
}

/* Subsection Styling */
.section-subsection {
    margin-bottom: 32px;
}

.subsection-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 16px;
}

.subsection-title {
    font-size: 15px;
    font-weight: 600;
    color: var(--text-light);
    margin: 0;
}

.info-grid-spacing {
    margin-bottom: 32px;
}

/* Empty State */
.empty-state-message {
    padding: 24px;
    text-align: center;
    color: var(--text-dim);
    font-size: 14px;
    border: 2px dashed color-mix(in srgb, var(--primary-color) 30%, transparent);
    border-radius: 8px;
}

/* Button Variants */
.btn-small {
    font-size: 13px;
    padding: 6px 12px;
}

.btn-danger {
    color: var(--danger-color);
    border-color: color-mix(in srgb, var(--danger-color) 30%, transparent);
}

.btn-danger:hover {
    background: color-mix(in srgb, var(--danger-color) 15%, transparent);
    border-color: color-mix(in srgb, var(--danger-color) 50%, transparent);
    color: var(--danger-color);
}

/* Label Optional Text */
.label-optional {
    color: var(--text-dim);
    font-weight: 400;
}

/* Stripe Elements Styling */
.stripe-element {
    padding: 10px 12px;
    border: 1px solid color-mix(in srgb, var(--primary-color) 25%, transparent);
    border-radius: 6px;
    background: color-mix(in srgb, var(--panel-75) 70%, transparent 30%);
    backdrop-filter: blur(6px);
    transition: all 0.2s ease;
    min-height: 42px;
    width: 100%;
    box-sizing: border-box;
    position: relative;
}

.stripe-element:focus-within {
    border-color: var(--primary-color);
    background: color-mix(in srgb, var(--panel-75) 85%, transparent 15%);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary-color) 20%, transparent), 0 2px 8px var(--shadow-primary-25);
    outline: none;
}

.stripe-element.StripeElement--invalid {
    border-color: var(--danger-color);
}

.stripe-element.StripeElement--complete {
    border-color: var(--secondary-color);
}

/* Ensure Stripe iframe fills container */
.stripe-element iframe {
    width: 100% !important;
    min-height: 22px;
}

.stripe-errors {
    color: var(--danger-color);
    font-size: 13px;
    margin-top: 8px;
    min-height: 20px;
    display: none;
}

.stripe-errors:not(:empty) {
    display: block;
}

/* Theme transition support */
.account-settings-page.theme-transitioning,
.account-settings-page.theme-transitioning * {
    transition: background-color 0.3s ease, 
                color 0.3s ease, 
                border-color 0.3s ease,
                box-shadow 0.3s ease !important;
}

/* Browser compatibility fallbacks for new classes */
@supports not (background: color-mix(in srgb, white 50%, black)) {
    .empty-state-message {
        border: 2px dashed rgba(59, 130, 246, 0.3);
    }
    
    .btn-danger {
        border-color: rgba(236, 72, 153, 0.3);
    }
    
    .btn-danger:hover {
        background: rgba(236, 72, 153, 0.15);
        border-color: rgba(236, 72, 153, 0.5);
    }
}

/* Mobile: Remove backdrop-filter for performance */
@media (hover: none) {
    .settings-section,
    .payment-card,
    .billing-address-box,
    .modal-content-professional,
    .btn-professional,
    .form-group-professional input,
    .form-group-professional select,
    .stripe-element {
        backdrop-filter: none;
    }
    
    .settings-section {
        background: var(--panel-90);
    }
    
    .stripe-element {
        background: var(--panel-75);
    }
    
    .payment-card {
        background: var(--panel-90);
    }
    
    .billing-address-box {
        background: var(--panel-75);
    }
    
    .modal-content-professional {
        background: var(--panel-90);
    }
    
    .btn-professional {
        background: var(--panel-75);
    }
    
    .form-group-professional input,
    .form-group-professional select {
        background: var(--panel-75);
    }
}

/* Browser compatibility fallbacks */
@supports not (background: color-mix(in srgb, white 50%, black)) {
    .account-settings-page {
        background: linear-gradient(135deg, #031120 0%, #154772 100%);
    }
    
    .settings-section {
        border: 1px solid rgba(59, 130, 246, 0.15);
        background: rgba(27, 42, 106, 0.9);
    }
    
    .section-header {
        border-bottom: 1px solid rgba(59, 130, 246, 0.15);
        background: rgba(27, 42, 106, 0.75);
    }
    
    .action-row {
        border-bottom: 1px solid rgba(59, 130, 246, 0.08);
    }
    
    .btn-professional {
        border: 1px solid rgba(59, 130, 246, 0.25);
        background: rgba(27, 42, 106, 0.75);
    }
    
    .btn-professional:hover {
        border-color: rgba(59, 130, 246, 0.4);
        background: rgba(27, 42, 106, 0.6);
    }
    
    .payment-card {
        border: 1px solid rgba(59, 130, 246, 0.15);
        background: rgba(27, 42, 106, 0.9);
    }
    
    .billing-address-box {
        border: 1px solid rgba(59, 130, 246, 0.15);
        background: rgba(27, 42, 106, 0.75);
    }
    
    .modal-professional {
        background: rgba(3, 17, 32, 0.7);
    }
    
    .modal-content-professional {
        border: 1px solid rgba(59, 130, 246, 0.25);
        background: rgba(27, 42, 106, 0.9);
    }
    
    .modal-header-professional {
        border-bottom: 1px solid rgba(59, 130, 246, 0.15);
    }
    
    .form-group-professional input,
    .form-group-professional select {
        border: 1px solid rgba(59, 130, 246, 0.25);
        background: rgba(27, 42, 106, 0.75);
    }
    
    .form-group-professional input:focus,
    .form-group-professional select:focus {
        box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2);
        background: rgba(27, 42, 106, 0.85);
    }
    
    .stripe-element {
        border: 1px solid rgba(59, 130, 246, 0.25);
        background: rgba(27, 42, 106, 0.75);
    }
    
    .stripe-element:focus-within {
        border-color: rgba(59, 130, 246, 1);
        box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2);
        background: rgba(27, 42, 106, 0.85);
    }
    
    .modal-actions-professional {
        border-top: 1px solid rgba(59, 130, 246, 0.15);
    }
}

/* Offering shared campaigns before deletion (S-6 FR-14) */
.delete-shared-campaigns {
    margin-bottom: 16px;
    padding: 12px;
    border: 1px solid var(--border-color);
    border-radius: 8px;
}

.delete-shared-intro {
    margin: 0 0 10px;
    font-size: 0.9em;
}

.delete-shared-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    padding: 6px 0;
}

.delete-shared-row strong {
    flex: 1 1 100%;
}

.delete-shared-status {
    font-size: 0.85em;
    color: var(--text-secondary, var(--text-dim));
}

.delete-shared-row select {
    flex: 1;
    min-width: 0;
    padding: 6px 8px;
    border: 1px solid var(--border-color);
    border-radius: 6px;
    background: var(--surface-panel);
    color: var(--text-light);
}


/* pages/_dice-tray.css */
/**
 * Dice Tray Page Styles
 * Styles for the animated dice roller with character context and quick actions
 */

body.dice-tray-page {
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    /* Solid dark base first so the page is never white (e.g. as a standalone
       popup window) if the themed gradient fails to resolve; hardcoded hex
       fallbacks in case the theme vars aren't loaded. */
    background-color: var(--theme-color-2, #031120);
    background-image: linear-gradient(135deg, var(--theme-color-2, #031120) 0%, var(--theme-color-1, #154772) 100%);
    color: var(--text-light, #d5f6ff);
    overflow: hidden;
    position: fixed;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
}

.dice-tray-page {
    --tray-base: color-mix(in srgb, var(--theme-color-2) 92%, transparent 8%);
    --tray-panel: color-mix(in srgb, var(--theme-color-1) 65%, var(--theme-color-2) 35%);
    --tray-overlay: color-mix(in srgb, var(--theme-color-1) 45%, transparent 55%);
    --tray-border: color-mix(in srgb, var(--primary-color) 45%, transparent);
    --tray-glow: color-mix(in srgb, var(--accent-color) 40%, transparent 60%);
}

#dice-tray-wrapper {
    width: min(98%, 1032px);
    height: calc(100% - 24px);
    display: flex;
    flex-direction: column;
}

.character-context-top-area {
    grid-row: 1;
    width: 100%;
    display: flex;
    flex-direction: row;
    gap: 12px;
    align-items: stretch;
    margin-bottom: 8px;
}

.dice-tray-main {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 200px;
    align-items: stretch;
    gap: 12px;
    min-height: 0;
    flex: 1 1 0;
    overflow: hidden;
}

/* When combat tab is active, make controls panel wider to fit cards properly */
body:has(#combat-tab.active) .dice-tray-main {
    grid-template-columns: minmax(300px, 1fr) 350px;
}

#dice-box {
    width: 100%;
    aspect-ratio: 1;
    max-height: 100%;
    min-height: 400px;
    min-width: 300px;
    border-radius: 12px;
    overflow: hidden;
    box-shadow: 0 12px 36px rgba(0, 0, 0, 0.35);
    background: color-mix(in srgb, var(--theme-color-2) 95%, transparent);
    position: relative;
    margin: auto;
}

#dice-box canvas {
    width: 100% !important;
    height: 100% !important;
    display: block !important;
}

.controls-panel {
    position: relative;
    background: var(--tray-base);
    border: 2px solid var(--tray-border);
    border-radius: 10px;
    padding: 8px;
    width: 200px;
    backdrop-filter: blur(10px);
    box-shadow: 0 8px 32px color-mix(in srgb, var(--shadow-color) 45%, transparent);
    z-index: 2;
    transition: width 0.3s ease, transform 0.3s ease, opacity 0.3s ease;
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden; /* Prevent panel from scrolling - let inner containers handle it */
    height: 100%;
}

/* When combat tab is active, widen the controls panel to fit cards */
body:has(#combat-tab.active) .controls-panel {
    width: 350px;
}

/* Tab Navigation */
.dice-tray-tabs {
    display: flex;
    flex-direction: row;
    gap: 4px;
    margin-bottom: 8px;
    border-bottom: 2px solid color-mix(in srgb, var(--primary-color) 30%, transparent);
    padding-bottom: 4px;
}

.dice-tray-tab {
    flex: 1;
    padding: 6px 8px;
    background: color-mix(in srgb, var(--tray-panel) 60%, transparent);
    border: 1px solid color-mix(in srgb, var(--primary-color) 30%, transparent);
    border-radius: 4px;
    color: var(--text-light);
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    cursor: pointer;
    transition: all 0.2s ease;
    text-align: center;
}

.dice-tray-tab:hover {
    background: color-mix(in srgb, var(--tray-panel) 80%, transparent);
    border-color: color-mix(in srgb, var(--primary-color) 50%, transparent);
}

.dice-tray-tab.active {
    background: var(--primary-color);
    border-color: var(--primary-color);
    color: var(--text-light);
    box-shadow: 0 0 8px color-mix(in srgb, var(--primary-color) 50%, transparent);
}

/* Tab Content */
.dice-tray-tab-content {
    flex: 1 1 0; /* Use flex-basis 0 to force height constraint */
    display: flex;
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
}

.tab-panel {
    display: none;
    flex: 1 1 0; /* Use flex-basis 0 to force height constraint */
    flex-direction: column;
    min-height: 0;
    overflow: hidden;
}

.tab-panel.active {
    display: flex;
}

/* Combat Participants Container - MUST have constrained height to show scrollbar */
.combat-participants-container {
    flex: 1 1 0; /* Use flex-basis 0 to force height constraint */
    overflow-y: auto;
    overflow-x: hidden;
    min-height: 0;
    width: 100%;
    position: relative;
    max-height: 100%;
}

/* Custom scrollbar for combat participants - make it more visible */
.combat-participants-container::-webkit-scrollbar {
    width: 12px;
}

.combat-participants-container::-webkit-scrollbar-track {
    background: color-mix(in srgb, var(--tray-base) 80%, transparent);
    border-radius: 6px;
    margin: 4px 0;
    border: 1px solid color-mix(in srgb, var(--primary-color) 30%, transparent);
}

.combat-participants-container::-webkit-scrollbar-thumb {
    background: var(--primary-color);
    border-radius: 6px;
    border: 2px solid color-mix(in srgb, var(--tray-base) 80%, transparent);
    min-height: 40px;
}

.combat-participants-container::-webkit-scrollbar-thumb:hover {
    background: var(--accent-color);
    border-color: var(--accent-color);
}

/* Firefox scrollbar */
.combat-participants-container {
    scrollbar-width: auto; /* Changed from thin to auto for better visibility */
    scrollbar-color: var(--primary-color) color-mix(in srgb, var(--tray-base) 80%, transparent);
}

.combat-participants-grid {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 4px;
    width: 100%;
}

/* Override combat tracker card width for dice tray - cards need 280px minimum */
.dice-tray-page .combat-participants-container .item-card,
.dice-tray-page .combat-participants-container .combat-carousel .item-card,
.dice-tray-page #combat-participants-grid .item-card,
.dice-tray-page #combat-participants-grid .combat-carousel .item-card {
    flex: 0 0 auto !important;
    min-width: 280px !important;
    max-width: 100% !important;
    width: 100% !important;
    flex-basis: auto !important;
}

/* Ensure cards maintain proper aspect ratio and don't get squished */
.dice-tray-page .combat-participants-container .combat-card-wrapper {
    min-width: 280px;
    width: 100%;
}

/* Ensure dice box area adjusts when combat tab is active */
body:has(#combat-tab.active) #dice-box {
    min-width: 300px;
}

/* Make sure the combat participants container takes available space */
#combat-tab.active {
    min-width: 0;
    overflow: visible;
}

/* Ensure combat participants grid doesn't use carousel layout in dice tray */
.dice-tray-page .combat-participants-container .combat-participants-grid,
.dice-tray-page #combat-participants-grid {
    display: flex !important;
    flex-direction: column !important;
    gap: 8px;
    padding: 4px;
    width: 100%;
    flex-wrap: nowrap !important;
}

.combat-participants-loading,
.combat-participants-empty {
    text-align: center;
    padding: 20px;
    color: var(--text-light);
    opacity: 0.7;
    font-size: 12px;
}

/* Custom scrollbar for controls panel */
.controls-panel::-webkit-scrollbar {
    width: 6px;
}

.controls-panel::-webkit-scrollbar-track {
    background: color-mix(in srgb, var(--tray-base) 60%, transparent 40%);
    border-radius: 3px;
}

.controls-panel::-webkit-scrollbar-thumb {
    background: var(--primary-color);
    border-radius: 3px;
}

.controls-panel::-webkit-scrollbar-thumb:hover {
    background: var(--accent-color);
}

.brand-header {
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 6px;
}

.brand-logo {
    width: 48px;
    height: auto;
    filter: drop-shadow(0 0 4px rgba(168, 85, 247, 0.5));
}

.controls-panel h2 {
    color: var(--primary-color);
    margin-bottom: 15px;
    font-size: 18px;
    text-align: center;
    border-bottom: 2px solid color-mix(in srgb, var(--primary-color) 30%, transparent);
    padding-bottom: 10px;
}

.roll-input-group {
    margin-bottom: 15px;
}

.roll-input-group label {
    display: block;
    margin-bottom: 5px;
    font-size: 12px;
    color: var(--primary-color);
    text-transform: uppercase;
    letter-spacing: 1px;
}

.roll-input {
    width: 100%;
    padding: 10px;
    background: var(--panel-60);
    border: 1px solid color-mix(in srgb, var(--primary-color) 40%, transparent);
    border-radius: 6px;
    color: var(--text-light);
    font-size: 16px;
    font-family: 'Courier New', monospace;
}

.roll-input:focus {
    outline: none;
    border-color: var(--primary-color);
    box-shadow: 0 0 12px color-mix(in srgb, var(--primary-color) 45%, transparent);
}

.quick-rolls {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 8px;
    margin-bottom: 15px;
}

.dice-settings {
    display: flex;
    flex-direction: column;
    gap: 18px;
    margin-bottom: 18px;
    padding: 16px;
    background: var(--panel-75);
    border: 1px solid color-mix(in srgb, var(--primary-color) 40%, transparent);
    border-radius: 6px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}

.dice-type-selector,
.dice-quantity-selector,
.modifier-selector {
    background: transparent;
    border: none;
    border-radius: 8px;
    padding: 0;
}

.selector-label {
    color: var(--primary-color);
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    text-align: center;
    margin-bottom: 8px;
}

.selector-controls {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 12px 48px;
    background: var(--panel-60);
    border: 1px solid color-mix(in srgb, var(--primary-color) 40%, transparent);
    border-radius: 6px;
    box-shadow: 0 0 8px color-mix(in srgb, var(--primary-color) 20%, transparent) inset;
}

.selector-btn {
    position: absolute;
    top: 6px;
    width: 34px;
    bottom: 6px;
    background: color-mix(in srgb, var(--secondary-color) 18%, transparent 82%);
    border: 1px solid color-mix(in srgb, var(--secondary-color) 50%, transparent);
    border-radius: 6px;
    color: var(--text-light);
    font-size: 18px;
    font-weight: bold;
    cursor: pointer;
    transition: all 0.2s;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Courier New', monospace;
}

.selector-btn.left {
    left: 6px;
}

.selector-btn.right {
    right: 6px;
}

.selector-btn:hover {
    background: color-mix(in srgb, var(--secondary-color) 28%, transparent 72%);
    transform: translateY(-1px);
    box-shadow: 0 6px 12px color-mix(in srgb, var(--secondary-color) 35%, transparent);
}

.selector-btn:active {
    transform: translateY(0);
    background: color-mix(in srgb, var(--secondary-color) 22%, transparent 78%);
}

.dice-display,
.quantity-display,
.modifier-display {
    background: transparent;
    border: none;
    padding: 0;
    color: var(--text-light);
    font-size: 18px;
    font-weight: bold;
    min-width: 70px;
    text-align: center;
    text-shadow: none;
    box-shadow: none;
    font-family: 'Courier New', monospace;
}

.modifier-display {
    text-transform: uppercase;
}

.action-buttons {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-bottom: 16px;
}

.action-buttons .action-row {
    display: flex;
    gap: 8px;
}

.action-buttons .action-row .action-btn {
    flex: 1;
    min-width: 0;
}

.action-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 10px 12px;
    background: color-mix(in srgb, var(--tray-overlay) 75%, transparent 25%);
    border: 2px solid var(--tray-border);
    border-radius: 10px;
    color: var(--primary-color);
    cursor: pointer;
    font-size: 13px;
    font-weight: bold;
    transition: all 0.2s;
    text-transform: none;
    letter-spacing: 0;
    box-shadow: 0 6px 18px color-mix(in srgb, var(--shadow-color) 35%, transparent);
    font-family: 'Courier New', monospace;
}

.action-btn:hover {
    transform: translateY(-2px);
    background: color-mix(in srgb, var(--tray-overlay) 85%, transparent 15%);
    box-shadow: 0 10px 24px color-mix(in srgb, var(--primary-color) 35%, transparent);
}

.action-btn:focus {
    outline: none;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary-color) 45%, transparent), 0 10px 24px color-mix(in srgb, var(--primary-color) 35%, transparent);
}

.action-btn:active {
    transform: translateY(0);
    background: color-mix(in srgb, var(--tray-overlay) 80%, transparent 20%);
}

#result {
    background: color-mix(in srgb, var(--tray-overlay) 70%, transparent 30%);
    border: 2px solid color-mix(in srgb, var(--primary-color) 50%, transparent);
    border-radius: 6px;
    padding: 8px;
    text-align: center;
    font-size: 13px;
    font-weight: bold;
    color: var(--primary-color);
    min-height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 15px;
    box-shadow: 0 0 15px color-mix(in srgb, var(--primary-color) 30%, transparent);
}

/* Character Context Section - Compact Top Bar */
.character-context-section {
    display: flex;
    flex-direction: column;
    padding: 10px 14px;
    background: var(--panel-75);
    border: 1px solid color-mix(in srgb, var(--primary-color) 40%, transparent);
    border-radius: 6px;
    flex: 0 0 auto;
    min-width: 220px;
    max-width: 300px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}

.character-context-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 4px;
    padding-bottom: 4px;
    border-bottom: 1px solid color-mix(in srgb, var(--primary-color) 30%, transparent);
}

.character-context-header h3 {
    color: var(--primary-color);
    margin: 0;
    font-weight: 600;
    font-size: 0.85em;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.character-image {
    width: 48px;
    height: 48px;
    border-radius: 8px;
    object-fit: cover;
    border: 2px solid var(--tray-border);
    margin-right: 12px;
}

.clear-character-btn {
    background: transparent;
    border: 1px solid color-mix(in srgb, var(--primary-color) 30%, transparent);
    border-radius: 3px;
    color: var(--text-light);
    cursor: pointer;
    font-size: 14px;
    width: 18px;
    height: 18px;
    padding: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.15s;
    line-height: 1;
}

.clear-character-btn:hover {
    background: color-mix(in srgb, var(--danger-color, #ff4444) 20%, transparent);
    border-color: var(--danger-color, #ff4444);
    color: var(--danger-color, #ff4444);
}

.character-context-stats {
    color: var(--text-light);
    line-height: 1.5;
    font-size: 0.75em;
}

.character-level-info {
    margin-bottom: 4px;
    font-size: 0.7em;
    opacity: 0.75;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.character-hp-ac {
    display: flex;
    gap: 10px;
    margin-bottom: 6px;
    font-size: 0.72em;
}

.character-hp-ac > div {
    color: var(--text-light);
}

.character-hp-ac strong {
    color: var(--accent-color);
    margin-right: 3px;
    font-weight: 700;
}

.passive-scores {
    display: flex;
    flex-direction: row;
    gap: 10px;
    flex-wrap: wrap;
}

.passive-score {
    display: flex;
    gap: 4px;
    padding: 0;
    font-size: 0.72em;
    align-items: center;
}

.passive-score .label {
    opacity: 0.75;
    font-weight: 500;
}

.passive-score span:last-child {
    font-weight: 700;
    color: var(--accent-color);
}

/* Quick Actions Section - Simplified to Attack and Damage Only */
.quick-actions-section {
    padding: 8px 12px;
    background: var(--panel-75);
    border: 1px solid color-mix(in srgb, var(--primary-color) 40%, transparent);
    border-radius: 4px;
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: row;
    gap: 12px;
    align-items: center;
    justify-content: center;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}

.quick-action-btn {
    padding: 10px 20px;
    background: var(--panel-60);
    border: 2px solid color-mix(in srgb, var(--primary-color) 50%, transparent);
    border-radius: 6px;
    color: var(--primary-color);
    cursor: pointer;
    font-size: 0.9em;
    font-weight: 700;
    transition: all 0.2s ease;
    text-align: center;
    white-space: nowrap;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    flex: 1;
    max-width: 200px;
}

.quick-action-btn.primary {
    background: color-mix(in srgb, var(--primary-color) 20%, transparent);
    border-color: var(--primary-color);
    box-shadow: 0 0 12px color-mix(in srgb, var(--primary-color) 40%, transparent);
}

.quick-action-btn:hover {
    background: var(--panel-75);
    border-color: var(--primary-color);
    box-shadow: 0 0 16px color-mix(in srgb, var(--primary-color) 60%, transparent);
    transform: translateY(-2px);
}

.quick-action-btn.primary:hover {
    background: color-mix(in srgb, var(--primary-color) 30%, transparent);
    box-shadow: 0 0 20px color-mix(in srgb, var(--primary-color) 70%, transparent);
}

.quick-action-btn:active {
    transform: translateY(0);
}

.connection-warning {
    padding: 8px;
    background: color-mix(in srgb, var(--danger-color, #ff4444) 20%, transparent);
    border: 1px solid var(--danger-color, #ff4444);
    border-radius: 6px;
    color: var(--danger-color, #ff4444);
    font-size: 11px;
    text-align: center;
    margin-bottom: 12px;
}

/* Hidden/Visible utility classes */
.hidden {
    display: none !important;
}

.visible {
    display: block !important;
}

.quick-actions-section.visible {
    display: block !important;
}

/* Target and damage type selectors */
.target-selector.hidden,
.damage-type-selector.hidden {
    display: none !important;
}

.target-selector.visible,
.damage-type-selector.visible {
    display: block !important;
}

.target-select {
    width: 100%;
    padding: 6px;
    background: var(--panel-60);
    border: 1px solid color-mix(in srgb, var(--primary-color) 40%, transparent);
    border-radius: 4px;
    color: var(--text-light);
    font-size: 0.85em;
}

.target-select:focus {
    outline: none;
    border-color: var(--primary-color);
    box-shadow: 0 0 8px color-mix(in srgb, var(--primary-color) 30%, transparent);
}

/* Error notification */
.error-notification {
    position: fixed;
    top: 20px;
    right: 20px;
    padding: 12px 16px;
    background: color-mix(in srgb, var(--danger-color, #ff4444) 20%, transparent);
    border: 1px solid var(--danger-color, #ff4444);
    border-radius: 6px;
    color: var(--danger-color, #ff4444);
    z-index: 10000;
    font-size: 13px;
    font-weight: 600;
}

/* Loading state */
.character-context-section.loading {
    opacity: 0.6;
    pointer-events: none;
}

.quick-actions-section.disabled {
    pointer-events: none;
    opacity: 0.6;
}

/* Loading error message */
.loading-error {
    color: var(--danger-color, #ff4444);
    text-align: center;
    padding: 20px;
}

.loading-error h2 {
    margin: 0 0 10px 0;
    font-size: 18px;
}

.loading-error p {
    margin: 0;
    font-size: 14px;
}

/* Temporary element for computed style reading (legitimate exception) */
.temp-style-reader {
    position: absolute;
    visibility: hidden;
}

.loading {
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    text-align: center;
    font-size: 24px;
    color: var(--primary-color);
    z-index: 2000;
    background: var(--panel-90);
    padding: 20px 40px;
    border-radius: 8px;
    border: 1px solid var(--primary-color);
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
}

.loading.hidden {
    display: none !important;
}

.loading-spinner {
    width: 50px;
    height: 50px;
    border: 5px solid color-mix(in srgb, var(--primary-color) 20%, transparent);
    border-top-color: var(--primary-color);
    border-radius: 50%;
    animation: spin 1s linear infinite;
    margin: 20px auto;
}

@keyframes spin {
    to { transform: rotate(360deg); }
}

body.dice-tray-page .open-dice-tray-btn,
body.dice-tray-page.viewer-role .open-dice-tray-btn {
    display: none !important;
}


/* ============================================================================
   Manual Combat Roll Prompt
   Shown over the dice tray when a participant with per-card Manual mode ON
   triggers a roll — the player types the value they physically rolled.
   ============================================================================ */
.manual-combat-prompt {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
    background: rgba(0, 0, 0, 0.55);
}
.manual-combat-prompt.hidden {
    display: none;
}
.manual-combat-box {
    width: 100%;
    max-width: 320px;
    box-sizing: border-box;
    padding: 18px 18px 16px;
    border-radius: 12px;
    border: 1px solid var(--abyssal-glow, #3a6ea5);
    background: var(--panel-bg, #10161d);
    box-shadow: 0 8px 30px rgba(0, 0, 0, 0.5);
    text-align: center;
}
.manual-combat-title {
    font-size: 13px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    opacity: 0.75;
    margin-bottom: 8px;
}
.manual-combat-label {
    font-size: 15px;
    font-weight: 600;
    margin-bottom: 4px;
}
.manual-combat-hint {
    font-size: 13px;
    opacity: 0.8;
    margin-bottom: 12px;
}
.manual-combat-box input {
    width: 100%;
    box-sizing: border-box;
    padding: 10px 12px;
    font-size: 18px;
    text-align: center;
    border-radius: 8px;
    border: 1px solid var(--border-color, #3a4a5a);
    background: var(--panel-75, rgba(0, 0, 0, 0.25));
    color: inherit;
}
.manual-combat-error {
    min-height: 16px;
    font-size: 12px;
    color: var(--danger, #e06c6c);
    margin: 8px 0 4px;
}
.manual-combat-actions {
    display: flex;
    gap: 8px;
    margin-top: 6px;
}
.manual-combat-actions .action-btn {
    flex: 1;
}


/* pages/_store.css */
/**
 * Store Pages CSS
 * store.html (browse), store-listing.html, store-checkout.html, store-purchases.html
 */

/* The marketplace's banner and sidebar were replaced by the shared app bar;
   their styles went with them. See css/components/_app-bar.css. */

.review-submit-btn:focus-visible {
    outline: 2px solid white;
    outline-offset: 2px;
}

/* The Creator Dashboard link used to be hidden by an id selector and revealed
   by adding a class. The app bar hides links with the `hidden` attribute now —
   which is also what tells assistive technology — and an `id` rule outranks
   `.app-bar-link[hidden]`, so leaving these here kept the link invisible even
   while standing on the page it points at. Removed, not rewritten. */

/* Review form - extracted from store-listing inline styles */
.review-form-container {
    background: rgba(27, 42, 106, 0.4);
    border: 1px solid var(--abyssal-glow);
    border-radius: 8px;
    padding: 20px;
    margin-bottom: 20px;
}

.review-form-container h3 {
    margin-bottom: 15px;
    color: var(--abyssal-light);
}

.review-form-field {
    margin-bottom: 15px;
}

.review-form-field label {
    display: block;
    margin-bottom: 8px;
    color: var(--abyssal-light);
}

.rating-stars {
    display: flex;
    gap: 5px;
    cursor: pointer;
}

.rating-stars .star {
    font-size: 2em;
    color: #666;
    transition: color 0.2s;
}

.rating-stars .star:hover {
    color: #ffd700;
}

.review-textarea {
    width: 100%;
    min-height: 100px;
    background: rgba(27, 42, 106, 0.6);
    border: 1px solid var(--abyssal-glow);
    border-radius: 4px;
    padding: 10px;
    color: var(--abyssal-light);
    font-family: inherit;
}

.review-submit-btn {
    padding: 10px 20px;
    background: var(--abyssal-glow);
    border: none;
    border-radius: 4px;
    color: white;
    cursor: pointer;
    font-weight: bold;
}

.review-item-card {
    background: rgba(27, 42, 106, 0.4);
    border: 1px solid var(--abyssal-glow);
    border-radius: 8px;
    padding: 20px;
    margin-bottom: 15px;
}

.review-item-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: 10px;
}

.review-item-username {
    font-weight: bold;
    color: var(--abyssal-light);
    margin-bottom: 5px;
}

.review-item-rating {
    color: var(--abyssal-glow);
}

.review-item-date {
    color: var(--abyssal-light);
    opacity: 0.7;
    font-size: 0.9em;
}

.review-item-comment {
    color: var(--abyssal-light);
    margin-top: 10px;
    line-height: 1.6;
}

.review-item-actions {
    margin-top: 10px;
    display: flex;
    gap: 15px;
    align-items: center;
}

.review-helpful-btn {
    background: transparent;
    border: 1px solid var(--abyssal-glow);
    border-radius: 4px;
    padding: 5px 10px;
    color: var(--abyssal-light);
    cursor: pointer;
    font-size: 0.85em;
}

.review-helpful-btn:hover {
    background: rgba(168, 85, 247, 0.2);
}

.review-helpful-btn:focus-visible {
    outline: 2px solid var(--abyssal-glow);
    outline-offset: 2px;
}

.purchase-card-date {
    color: var(--abyssal-light);
    opacity: 0.7;
    margin-bottom: 10px;
}

.recover-purchase-hint {
    margin-top: 16px;
    font-size: 0.9em;
    opacity: 0.9;
}

.recover-purchase-btn {
    background: transparent;
    border: 1px solid var(--abyssal-glow);
    border-radius: 4px;
    padding: 6px 12px;
    color: var(--abyssal-light);
    cursor: pointer;
    font-size: inherit;
}

.recover-purchase-btn:hover {
    background: rgba(168, 85, 247, 0.2);
}

.store-page .pagination-btn:focus-visible,
.store-purchases-page .purchase-card-actions .action-btn:focus-visible {
    outline: 2px solid var(--abyssal-glow);
    outline-offset: 2px;
}

/* ============================================
   Store Browse (store.html) - .store-page
   ============================================ */
.store-page .store-container {
    max-width: var(--page-max);
    margin: 0 auto;
    padding: 20px;
    padding-top: 60px;
}

.store-page .store-header {
    margin-bottom: 30px;
}

.store-page .store-header h1 {
    color: var(--primary-color, var(--abyssal-glow));
    margin-bottom: 10px;
}

.store-page .store-header p {
    color: var(--text-light, var(--abyssal-light));
    opacity: 0.9;
}

.store-page .sell-cta-btn,
.store-purchases-page .sell-cta-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-top: 12px;
    padding: 10px 20px;
    background: linear-gradient(135deg, rgba(34, 197, 94, 0.3), rgba(34, 197, 94, 0.2));
    border: 1px solid var(--abyssal-glow);
    border-radius: 6px;
    color: var(--abyssal-light);
    text-decoration: none;
    font-weight: 500;
    transition: all 0.2s;
}

.store-page .sell-cta-btn:hover,
.store-purchases-page .sell-cta-btn:hover {
    background: linear-gradient(135deg, rgba(34, 197, 94, 0.5), rgba(34, 197, 94, 0.3));
    transform: translateY(-1px);
}

.sell-cta-icon {
    font-size: 1.2em;
}

.seller-badge {
    display: inline-block;
    padding: 2px 8px;
    background: rgba(168, 85, 247, 0.3);
    border-radius: 4px;
    font-size: 0.75em;
    font-weight: 600;
    color: var(--abyssal-glow);
    margin-right: 6px;
}

/* The listing caption's creator line is styled with the rest of the shelf
   below; this older rule sized it for the card layout that came before. */

.store-listing-page .sell-cta-inline {
    display: inline-block;
    margin-bottom: 20px;
    padding: 8px 16px;
    background: rgba(34, 197, 94, 0.2);
    border: 1px solid var(--abyssal-glow);
    border-radius: 4px;
    color: var(--abyssal-teal);
    text-decoration: none;
    font-size: 0.9em;
    transition: background 0.2s;
}

.store-listing-page .sell-cta-inline:hover {
    background: rgba(34, 197, 94, 0.35);
}

.store-page .store-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 15px;
    align-items: flex-end;
    margin-bottom: 25px;
}

.store-page .filter-group {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.store-page .filter-group label {
    font-size: 0.9em;
    color: var(--text-light, var(--abyssal-light));
}

.store-page .filter-select,
.store-page .filter-input {
    padding: 10px 14px;
    background: rgba(0, 0, 0, 0.3);
    border: 1px solid var(--border-color, var(--abyssal-glow));
    border-radius: 6px;
    color: var(--text-light);
    min-width: 140px;
}

/* Cover-width columns, matching Your Campaigns. 280px was sized for a 16:9
   thumbnail above a paragraph; a hardback needs less. */
.store-page .listings-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
    gap: 28px 24px;
}

@media (max-width: 560px) {
    .store-page .listings-grid {
        grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
        gap: 20px 16px;
    }
}

/* The same shelf as Your Campaigns — see _campaign-card.css, which owns
   .campaign-cover and is where the jacket, spine and hover blurb live. A
   listing reuses it so the two pages agree; what is different about a listing
   is the price, and that sits on the cover. */
.store-page .listing-card {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 12px;
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
}

.store-page .listing-card-price {
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: 2;
    padding: 4px 10px;
    border-radius: 20px;
    background: rgba(8, 16, 26, 0.82);
    border: 1px solid rgba(255, 255, 255, 0.18);
    backdrop-filter: blur(6px);
    color: #fff;
    font-size: 0.82rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.store-page .listing-card-content {
    display: flex;
    flex-direction: column;
    gap: 3px;
    padding: 0;
    min-width: 0;
}

.store-page .listing-card-title {
    font-size: 0.98rem;
    font-weight: 600;
    line-height: 1.35;
    color: var(--text-light);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.store-page .listing-card-creator {
    font-size: 0.82rem;
    color: var(--text-dim);
    opacity: 0.85;
    margin: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/*
 * A couple of lines of the description, under the cover rather than on it.
 *
 * This used to be `campaign-cover-blurb` inside the jacket, and no stylesheet
 * ever defined that class — so it rendered as a full unstyled paragraph across
 * the cover, clipped mid-sentence, with the title showing through from behind.
 * Clamped here so a long description gives two lines and an ellipsis instead of
 * however many the text happens to run to.
 */
.store-page .listing-card-blurb {
    margin: 4px 0 0;
    font-size: 0.8rem;
    line-height: 1.4;
    color: var(--text-dim);
    opacity: 0.9;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.store-page .listing-card-stats {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 2px;
    font-size: 0.74rem;
    color: var(--text-dim);
    opacity: 0.7;
}

.store-page .listing-card-rating {
    color: #f0c14b;
}

.store-page .pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 20px;
    margin-top: 30px;
}

.store-page .pagination.is-visible {
    display: flex;
}

.store-page .pagination-btn {
    padding: 10px 20px;
    background: rgba(168, 85, 247, 0.2);
    border: 1px solid var(--abyssal-glow);
    border-radius: 6px;
    color: var(--text-light);
    cursor: pointer;
}

.store-page .pagination-btn:hover:not(:disabled) {
    background: rgba(168, 85, 247, 0.4);
}

.store-page .pagination-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.store-page .pagination-btn:focus-visible {
    outline: 2px solid var(--abyssal-glow);
    outline-offset: 2px;
}

/* ============================================
   Store Listing Detail (store-listing.html)
   ============================================ */
.store-listing-page .listing-container {
    max-width: var(--page-max);
    margin: 0 auto;
    padding: 20px;
    padding-top: 60px;
}

/* Cover, then what it is, then what it costs. The page where somebody decides
   whether to buy had no picture of the thing at all. */
.store-listing-page .listing-header {
    display: grid;
    grid-template-columns: 230px 1fr 340px;
    gap: 32px;
    align-items: start;
    margin-bottom: 34px;
}

@media (max-width: 1100px) {
    .store-listing-page .listing-header {
        grid-template-columns: 200px 1fr;
    }

    /* The price panel drops below both, full width, rather than being squeezed. */
    .store-listing-page .listing-price-section {
        grid-column: 1 / -1;
    }
}

@media (max-width: 640px) {
    .store-listing-page .listing-header {
        grid-template-columns: 1fr;
    }

    .store-listing-page .listing-cover {
        max-width: 220px;
    }
}

/* Inherits the jacket, spine and hue from .campaign-cover; only the size is
   this page's business. */
.store-listing-page .listing-cover {
    width: 100%;
}

.store-listing-page .listing-info h1 {
    font-size: 2.5em;
    margin-bottom: 15px;
}

.store-listing-page .listing-meta {
    display: flex;
    gap: 20px;
    margin-bottom: 20px;
    color: var(--abyssal-light);
    opacity: 0.8;
}

.store-listing-page .listing-price-section {
    background: rgba(27, 42, 106, 0.4);
    border: 1px solid var(--abyssal-glow);
    border-radius: 8px;
    padding: 20px;
}

.store-listing-page .listing-price {
    font-size: 3em;
    font-weight: bold;
    color: var(--abyssal-glow);
    margin-bottom: 20px;
}

.store-listing-page .purchase-btn {
    width: 100%;
    padding: 15px;
    background: var(--abyssal-glow);
    border: none;
    border-radius: 4px;
    color: white;
    font-size: 1.1em;
    font-weight: bold;
    cursor: pointer;
    transition: opacity 0.2s;
}

.store-listing-page .purchase-btn:hover:not(:disabled) {
    opacity: 0.9;
}

.store-listing-page .purchase-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.store-listing-page .purchase-btn:focus-visible {
    outline: 2px solid white;
    outline-offset: 2px;
}

.store-listing-page .listing-stats {
    display: flex;
    gap: 30px;
    margin-top: 15px;
    font-size: 0.9em;
}

.store-listing-page .listing-content {
    margin-top: 40px;
}

.store-listing-page .content-section {
    margin-bottom: 30px;
}

.store-listing-page .content-section h2 {
    font-size: 1.5em;
    margin-bottom: 15px;
    color: var(--abyssal-light);
}

.store-listing-page .preview-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 15px;
}

.store-listing-page .preview-item {
    background: rgba(27, 42, 106, 0.4);
    border: 1px solid var(--abyssal-glow);
    border-radius: 4px;
    padding: 15px;
}

.store-listing-page .preview-item h3 {
    font-size: 1em;
    margin-bottom: 8px;
}

/* ============================================
   Store Checkout (store-checkout.html)
   ============================================ */
.store-checkout-page .checkout-container {
    max-width: 800px;
    margin: 0 auto;
    padding: 20px;
    padding-top: 60px;
}

.store-checkout-page .checkout-header {
    margin-bottom: 30px;
}

/* The panels used a hard-coded navy — rgba(27, 42, 106, …) — which is the
   Abyssal theme's ground colour written out by hand. On Solar Dawn or
   Firelands the page went warm and the payment form stayed blue. The tokens
   below follow whatever theme is on. */
.store-checkout-page .checkout-form {
    background: var(--panel-60);
    border: 1px solid var(--abyssal-glow);
    border-radius: 8px;
    padding: 30px;
}

.store-checkout-page .checkout-form .form-group {
    margin-bottom: 20px;
}

.store-checkout-page .checkout-form .form-group label {
    display: block;
    margin-bottom: 8px;
    color: var(--abyssal-light);
}

.store-checkout-page #card-element {
    background: var(--panel-75);
    border: 1px solid var(--abyssal-glow);
    border-radius: 4px;
    padding: 12px;
    color: var(--abyssal-light);
}

/* What you are buying, next to what it costs. This was a title and a number:
   the listing page leads with the cover, so the picture used to disappear at
   the exact moment somebody decides to hand over money. */
.store-checkout-page .checkout-summary {
    display: grid;
    grid-template-columns: 120px 1fr;
    gap: 20px;
    align-items: start;
    background: var(--surface-overlay);
    border: 1px solid var(--abyssal-glow);
    border-radius: 8px;
    padding: 20px;
    margin-bottom: 20px;
}

.store-checkout-page .checkout-cover {
    width: 120px;
    padding: 12px;
}

.store-checkout-page .checkout-summary-detail h2 {
    margin: 0 0 4px;
}

.store-checkout-page .checkout-creator {
    color: var(--abyssal-light);
    opacity: 0.8;
    margin-bottom: 16px;
}

.store-checkout-page .summary-row {
    display: flex;
    justify-content: space-between;
    margin-bottom: 10px;
}

/* Narrow screens: the cover leads, the detail sits under it. */
@media (max-width: 560px) {
    .store-checkout-page .checkout-summary {
        grid-template-columns: 1fr;
    }

    .store-checkout-page .checkout-cover {
        width: 140px;
    }
}

.store-checkout-page .summary-total {
    font-size: 1.5em;
    font-weight: bold;
    color: var(--abyssal-glow);
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid var(--abyssal-glow);
}

.store-checkout-page .submit-btn {
    width: 100%;
    padding: 15px;
    background: var(--abyssal-glow);
    border: none;
    border-radius: 4px;
    color: white;
    font-size: 1.1em;
    font-weight: bold;
    cursor: pointer;
    transition: opacity 0.2s;
}

.store-checkout-page .submit-btn:hover:not(:disabled) {
    opacity: 0.9;
}

.store-checkout-page .submit-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.store-checkout-page .error-message {
    color: var(--danger-color, #ff4444);
    margin-top: 10px;
}

/* Every way out of this page, and there was none before: a checkout that
   could not be completed was a dead end with the app bar as the only exit. */
.store-checkout-page .checkout-back {
    display: inline-block;
    margin-top: 18px;
    color: var(--abyssal-light);
    text-decoration: none;
    border-bottom: 1px solid var(--abyssal-glow);
    padding-bottom: 2px;
}

.store-checkout-page .checkout-back:hover {
    color: var(--abyssal-glow);
}

.store-checkout-page .checkout-form .checkout-back {
    display: block;
    text-align: center;
    border-bottom: none;
    opacity: 0.75;
}

/* showNotice() is only ever called for a failure, so the whole panel says so.
   It carried the theme highlight — a cyan or green box, which is what the rest
   of the app uses for things that went right. */
.store-checkout-page .checkout-notice {
    background: var(--panel-60);
    border: 1px solid color-mix(in srgb, var(--danger-color) 45%, transparent);
    border-radius: 8px;
    padding: 30px;
    text-align: center;
}

.store-checkout-page .checkout-notice .error-message {
    margin: 0;
    line-height: 1.5;
}

/* ============================================
   Store Purchases (store-purchases.html)
   ============================================ */
.store-purchases-page .purchases-container {
    max-width: var(--page-max);
    margin: 0 auto;
    padding: 20px;
    padding-top: 60px;
}

.store-purchases-page .purchases-header {
    margin-bottom: 30px;
}

/* The same shelf as the marketplace — see _campaign-card.css, which owns
   .campaign-cover. What a purchase adds is its actions, and those stay on
   screen rather than waiting for a hover: Download is the reason this page
   exists. */
.store-purchases-page .purchases-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
    gap: 28px 24px;
}

@media (max-width: 560px) {
    .store-purchases-page .purchases-grid {
        grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
        gap: 20px 16px;
    }
}

.store-purchases-page .purchase-card {
    display: flex;
    flex-direction: column;
    gap: 12px;
    background: none;
    border: none;
    padding: 0;
}

.store-purchases-page .purchase-card-body {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
}

.store-purchases-page .purchase-card-title {
    font-size: 0.98rem;
    font-weight: 600;
    line-height: 1.35;
    margin: 0;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.store-purchases-page .purchase-card-date {
    font-size: 0.78rem;
    opacity: 0.7;
    margin: 0;
}

.store-purchases-page .purchase-card-actions {
    display: flex;
    gap: 8px;
    margin-top: 8px;
}

.store-purchases-page .purchase-card-actions .action-btn {
    flex: 1;
    /* Buttons do not inherit the page font unless told to — these were
       rendering in the browser's default and wrapping onto two lines. */
    font-family: inherit;
    font-size: 0.8rem;
    padding: 7px 10px;
    background: rgba(168, 85, 247, 0.2);
    border: 1px solid var(--abyssal-glow);
    border-radius: 7px;
    color: var(--abyssal-light);
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.2s;
}

.store-purchases-page .purchase-card-actions .action-btn:hover:not(:disabled) {
    background: rgba(168, 85, 247, 0.4);
}

/*
 * The one action that is news rather than always-available.
 *
 * Update only appears when the creator has actually published something newer,
 * so it should read as an offer rather than as a third equal option sitting
 * beside Download and Restore.
 */
.store-purchases-page .purchase-card-actions .action-btn-highlight {
    background: rgba(52, 211, 153, 0.22);
    border-color: rgba(52, 211, 153, 0.85);
    font-weight: 600;
}

.store-purchases-page .purchase-card-actions .action-btn-highlight:hover:not(:disabled) {
    background: rgba(52, 211, 153, 0.38);
}

.store-purchases-page .purchase-card-actions .action-btn-link {
    text-decoration: none;
    text-align: center;
    flex: 1;
}

.store-purchases-page .purchase-card-actions .action-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

.store-purchases-page .progress-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.8);
    display: none;
    align-items: center;
    justify-content: center;
    z-index: 10000;
}

.store-purchases-page .progress-overlay.is-visible {
    display: flex;
}

.store-purchases-page .progress-content {
    background: rgba(27, 42, 106, 0.9);
    border: 1px solid var(--abyssal-glow);
    border-radius: 8px;
    padding: 30px;
    max-width: 400px;
    text-align: center;
}

.store-purchases-page .progress-bar {
    width: 100%;
    height: 20px;
    background: rgba(168, 85, 247, 0.2);
    border-radius: 10px;
    overflow: hidden;
    margin-top: 15px;
}

.store-purchases-page .progress-fill {
    height: 100%;
    width: 0;
    background: var(--abyssal-glow);
    transition: width 0.3s;
}


/* pages/_store-creator.css */
/**
 * Store Creator Page Styles
 * Creator dashboard, listing form modal, stats, tables
 * Matches store.html cards/stats and home.css patterns
 */

/* ============================================
   Dashboard Layout
   ============================================ */
.store-creator-page .dashboard-container {
    /* Was 1400 while its siblings were 1200, which made this the only store
       screen that lined up with the bar and the only one that did not line up
       with the others. */
    max-width: var(--page-max);
    margin: 0 auto;
    padding: 20px;
    padding-top: 60px;
    box-sizing: border-box;
}

.store-creator-page .dashboard-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 30px;
}

.store-creator-page .dashboard-header h1 {
    color: var(--primary-color, var(--abyssal-glow));
    margin: 0;
}

/* ============================================
   Stats Grid (match home/store stat cards)
   ============================================ */
.store-creator-page .stats-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
    gap: 20px;
    margin-bottom: 30px;
}

.store-creator-page .stat-card {
    background: rgba(27, 42, 106, 0.4);
    border: 1px solid var(--abyssal-glow, var(--primary-color));
    border-radius: 8px;
    padding: 20px;
    text-align: center;
    transition: transform 0.2s, box-shadow 0.2s;
}

.store-creator-page .stat-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(168, 85, 247, 0.3);
}

.store-creator-page .stat-value {
    font-size: 2.5em;
    font-weight: bold;
    color: var(--abyssal-glow, var(--primary-color));
}

.store-creator-page .stat-label {
    color: var(--abyssal-light, var(--text-light));
    opacity: 0.8;
    margin-top: 10px;
    font-size: 0.9em;
}

/* ============================================
   Tabs
   ============================================ */
.store-creator-page .dashboard-tabs {
    display: flex;
    gap: 10px;
    margin-bottom: 20px;
    border-bottom: 1px solid var(--abyssal-glow, var(--border-color));
}

.store-creator-page .tab-btn {
    padding: 10px 20px;
    background: transparent;
    border: none;
    border-bottom: 2px solid transparent;
    color: var(--abyssal-light, var(--text-light));
    cursor: pointer;
    transition: border-color 0.2s, color 0.2s;
}

.store-creator-page .tab-btn:hover {
    color: var(--abyssal-glow, var(--primary-color));
}

.store-creator-page .tab-btn:focus-visible {
    outline: 2px solid var(--abyssal-glow, var(--primary-color));
    outline-offset: 2px;
}

.store-creator-page .tab-btn.active {
    border-bottom-color: var(--abyssal-glow, var(--primary-color));
    color: var(--abyssal-glow, var(--primary-color));
}

.store-creator-page .tab-content {
    display: none;
}

.store-creator-page .tab-content.active {
    display: block;
}

/* ============================================
   Listings / Sales Tables
   ============================================ */
.store-creator-page .listings-table {
    width: 100%;
    border-collapse: collapse;
}

.store-creator-page .listings-table th,
.store-creator-page .listings-table td {
    padding: 12px;
    text-align: left;
    border-bottom: 1px solid rgba(168, 85, 247, 0.2);
}

.store-creator-page .listings-table th {
    color: var(--abyssal-glow, var(--primary-color));
    font-weight: bold;
}

.store-creator-page .listings-table tbody tr:hover {
    background: rgba(168, 85, 247, 0.05);
}

/* Status badges */
.store-creator-page .status-badge {
    padding: 4px 12px;
    border-radius: 12px;
    font-size: 0.85em;
    display: inline-block;
}

.store-creator-page .status-draft {
    background: rgba(255, 255, 255, 0.1);
    color: var(--abyssal-light, var(--text-light));
}

.store-creator-page .status-published {
    background: rgba(0, 255, 0, 0.2);
    color: #00ff00;
}

.store-creator-page .status-pending_review {
    background: rgba(250, 204, 21, 0.18);
    color: #facc15;
}

.store-creator-page .status-rejected,
.store-creator-page .status-suspended {
    background: rgba(248, 113, 113, 0.18);
    color: #f87171;
}

.store-creator-page .status-note {
    display: block;
    margin-top: 4px;
    font-size: 0.85em;
    opacity: 0.85;
}

/* ============================================
   Action Buttons
   ============================================ */
/*
 * The actions cell holds a mix of <button> and <a>, and they have to look like
 * one set.
 *
 * They did not: an <a> is inline and keeps the link underline, so next to a
 * real button it rendered underlined and stretched across its own line, while
 * `margin-right` was doing the spacing and nothing was doing the alignment. It
 * only showed once there were two of them — with a single View link there was
 * nothing to be out of line with.
 */
.store-creator-page .listing-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}

.store-creator-page .action-btn {
    /* Buttons do not inherit the page font unless told to, so this one rendered
       in the browser's default while everything around it did not. */
    font-family: inherit;
    /* inline-flex so an <a> and a <button> size and align identically. */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 6px 12px;
    background: rgba(168, 85, 247, 0.2);
    border: 1px solid var(--abyssal-glow, var(--primary-color));
    border-radius: 4px;
    color: var(--abyssal-light, var(--text-light));
    cursor: pointer;
    font-size: 0.9em;
    line-height: 1.4;
    white-space: nowrap;
    text-decoration: none;
    transition: background 0.2s;
}

.store-creator-page .action-btn:hover {
    background: rgba(168, 85, 247, 0.4);
}

.store-creator-page .action-btn:focus-visible {
    outline: 2px solid var(--abyssal-glow, var(--primary-color));
    outline-offset: 2px;
}

.store-creator-page .action-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
}

/* ============================================
   Create Listing Modal - Responsive Grid
   ============================================ */
.store-creator-page .create-listing-layout {
    display: grid;
    grid-template-columns: 1fr 320px;
    gap: 24px;
}

@media (max-width: 900px) {
    .store-creator-page .create-listing-layout {
        grid-template-columns: 1fr;
    }
}

.store-creator-page .form-column {
    min-width: 0;
}

/* Form inputs in modal */
.store-creator-page #create-listing-modal .form-section {
    margin-bottom: 24px;
}

.store-creator-page #create-listing-modal .form-section h3 {
    color: var(--secondary-color, var(--abyssal-glow));
    margin-bottom: 12px;
    font-size: 1.1em;
}

.store-creator-page #create-listing-modal .form-group input[readonly] {
    background: rgba(0, 0, 0, 0.2);
    cursor: default;
}

.store-creator-page #create-listing-modal .cover-preview {
    max-width: 200px;
    max-height: 120px;
    border-radius: 8px;
    object-fit: cover;
    margin-top: 8px;
}

.store-creator-page #create-listing-modal .error-message {
    color: var(--accent-color, #ff6b6b);
    margin-bottom: 12px;
    font-size: 0.9em;
}

/* Preview pane (match listing card style from store) */
.store-creator-page .listing-preview-pane {
    background: rgba(0, 0, 0, 0.3);
    border: 1px solid var(--abyssal-glow, var(--border-color));
    border-radius: 12px;
    padding: 20px;
    height: fit-content;
    position: sticky;
    top: 20px;
}

@media (max-width: 900px) {
    .store-creator-page .listing-preview-pane {
        position: static;
    }
}

.store-creator-page .listing-preview-pane h4 {
    margin: 0 0 12px;
    color: var(--abyssal-glow, var(--primary-color));
    font-size: 0.9em;
    text-transform: uppercase;
}

.store-creator-page .preview-card {
    background: rgba(27, 42, 106, 0.5);
    border-radius: 8px;
    overflow: hidden;
    border: 1px solid rgba(168, 85, 247, 0.3);
}

.store-creator-page .preview-card-image {
    position: relative;
    width: 100%;
    aspect-ratio: 16/9;
    background: rgba(0, 0, 0, 0.4);
    overflow: hidden;
}

.store-creator-page .preview-card-image__img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: none;
}

.store-creator-page .preview-card-image__img.is-visible {
    display: block;
}

.store-creator-page .preview-card-content {
    padding: 12px;
}

.store-creator-page .preview-card-title {
    font-weight: bold;
    color: var(--abyssal-light, var(--text-light));
    margin-bottom: 6px;
}

.store-creator-page .preview-card-desc {
    font-size: 0.85em;
    color: var(--abyssal-light, var(--text-light));
    opacity: 0.8;
    margin-bottom: 8px;
    max-height: 60px;
    overflow: hidden;
}

.store-creator-page .preview-card-meta {
    display: flex;
    justify-content: space-between;
    font-size: 0.85em;
    color: var(--abyssal-glow, var(--primary-color));
}

/* Modal actions */
.store-creator-page #create-listing-modal .modal-actions {
    display: flex;
    gap: 12px;
    flex-wrap: wrap;
    margin-top: 20px;
}

.store-creator-page #create-listing-modal .modal-actions .btn {
    flex-shrink: 0;
}

.store-creator-page #create-listing-modal .modal-actions .btn:focus-visible {
    outline: 2px solid var(--abyssal-glow, var(--primary-color));
    outline-offset: 2px;
}

/* Dashboard error state */
.store-creator-page .dashboard-error {
    color: var(--accent-color, #ff6b6b);
}

/* Utility: hidden state (replaces inline style display:none) */
.store-creator-page .is-hidden {
    display: none;
}


/* pages/_admin.css */
/**
 * Admin / Support Portal Page
 * User management styling
 */

.admin-page {
    /* The rules below were written against a light palette whose variables the
       theme never defines, so they fell back to light backgrounds while inherited
       text stayed the theme's light colour. Map them onto the theme instead. */
    --text-primary: var(--text-light);
    --text-secondary: var(--text-dim);
    --bg-primary: var(--surface-base);
    --bg-secondary: var(--surface-panel);
    --bg-tertiary: color-mix(in srgb, var(--surface-panel) 70%, var(--surface-base) 30%);
    --bg-hover: var(--accent-primary-20);
    --admin-danger: #f87171;
    /* The portal's column, through the shared token like every other page. */
    --page-max: 1240px;

    background: var(--bg-primary, #f8f9fa);
    color: var(--text-primary);
    min-height: 100vh;
    padding-top: 60px;
}

.admin-container {
    max-width: var(--page-max);
    margin: 0 auto;
    padding: 40px 24px;
}

.admin-header {
    margin-bottom: 32px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 16px;
}

.admin-header h1 {
    font-size: 28px;
    font-weight: 600;
    color: var(--text-primary, #1a1a1a);
    margin: 0;
}

.admin-header p {
    font-size: 14px;
    color: var(--text-secondary, #6b7280);
    margin: 8px 0 0 0;
}

.admin-section {
    background: var(--bg-secondary, #ffffff);
    border-radius: 8px;
    border: 1px solid var(--border-color, #e5e7eb);
    margin-bottom: 24px;
    overflow: hidden;
}

.admin-section__header {
    padding: 20px 24px;
    border-bottom: 1px solid var(--border-color, #e5e7eb);
    background: var(--bg-tertiary, #fafafa);
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.admin-section__header h2 {
    font-size: 16px;
    font-weight: 600;
    color: var(--text-primary, #111827);
    margin: 0;
}

.admin-section__content {
    padding: 24px;
}

.admin-nav {
    display: flex;
    align-items: center;
    gap: 16px;
}

.admin-nav__username {
    color: var(--text-secondary);
    font-size: 14px;
}

.admin-nav a {
    color: var(--text-secondary);
    text-decoration: none;
    font-size: 14px;
}

.admin-nav a:hover,
.admin-nav a:focus-visible {
    color: var(--text-primary);
}

.admin-nav__refresh,
.admin-nav .btn {
    padding: 8px 16px;
    font-size: 13px;
}

.admin-nav__refresh:focus-visible,
.admin-nav .btn:focus-visible {
    outline: 2px solid var(--accent-color, #3b82f6);
    outline-offset: 2px;
}

/* Users table */
.admin-users-table-container {
    overflow-x: auto;
}

.admin-users-table {
    width: 100%;
    border-collapse: collapse;
}

.admin-users-table th {
    text-align: left;
    padding: 12px 16px;
    font-size: 12px;
    font-weight: 600;
    color: var(--text-secondary, #6b7280);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    border-bottom: 2px solid var(--border-color, #e5e7eb);
    background: var(--bg-tertiary, #fafafa);
}

.admin-users-table td {
    padding: 16px;
    border-bottom: 1px solid var(--border-color, #e5e7eb);
    color: var(--text-primary, #111827);
}

.admin-users-table tr:hover {
    background: var(--bg-hover, #f9fafb);
}

.admin-badge {
    display: inline-flex;
    align-items: center;
    padding: 4px 12px;
    border-radius: 12px;
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.admin-badge--admin {
    background: #fef3c7;
    color: #92400e;
}

.admin-badge--free {
    background: #f3f4f6;
    color: #374151;
}

.admin-badge--premium {
    background: #dbeafe;
    color: #1e40af;
}

.admin-badge--active {
    background: #d1fae5;
    color: #065f46;
}

.admin-badge--inactive {
    background: #fee2e2;
    color: #991b1b;
}

.admin-badge--suspended {
    background: #fef3c7;
    color: #92400e;
}

.admin-form-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
    gap: 20px;
    margin-bottom: 20px;
}

.admin-form-group {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.admin-form-group label {
    font-size: 13px;
    font-weight: 500;
    color: var(--text-primary, #111827);
}

.admin-form-group input,
.admin-form-group select {
    padding: 10px 12px;
    border: 1px solid var(--border-color, #d1d5db);
    border-radius: 6px;
    font-size: 14px;
    background: var(--bg-primary, #ffffff);
    color: var(--text-primary, #111827);
}

.admin-form-group input:focus,
.admin-form-group input:focus-visible,
.admin-form-group select:focus,
.admin-form-group select:focus-visible {
    outline: none;
    border-color: var(--accent-color, #3b82f6);
    box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}

.admin-form-group small {
    font-size: 11px;
    color: var(--text-secondary, #6b7280);
}

.admin-btn-group {
    display: flex;
    gap: 12px;
    margin-top: 20px;
}

.admin-action-btn {
    padding: 6px 12px;
    font-size: 12px;
    border: 1px solid var(--border-color, #d1d5db);
    border-radius: 4px;
    background: var(--bg-primary, #ffffff);
    color: var(--text-primary, #111827);
    cursor: pointer;
}

.admin-action-btn:hover,
.admin-action-btn:focus-visible {
    background: var(--bg-hover, #f9fafb);
}

.admin-action-btn:focus-visible {
    outline: 2px solid var(--accent-color, #3b82f6);
    outline-offset: 2px;
}

.admin-action-group {
    display: flex;
    gap: 8px;
}

.admin-empty-value {
    color: var(--text-secondary, #9ca3af);
}

.admin-user-count {
    font-size: 13px;
    color: var(--text-secondary, #6b7280);
}

.admin-nav__refresh {
    background: var(--bg-tertiary, #f3f4f6);
    border: 1px solid var(--border-color, #d1d5db);
    border-radius: 6px;
    cursor: pointer;
    font-size: 13px;
    color: var(--text-primary, #111827);
}

.admin-nav__refresh:hover {
    background: var(--bg-hover, #e5e7eb);
}

.admin-loading {
    text-align: center;
    padding: 40px;
    color: var(--text-secondary, #6b7280);
}

.admin-empty-state {
    text-align: center;
    padding: 60px 20px;
    color: var(--text-secondary, #6b7280);
}

.admin-hidden {
    display: none;
}

.admin-error-message {
    background: #fee2e2;
    color: #991b1b;
    padding: 12px 16px;
    border-radius: 6px;
    margin-bottom: 20px;
    display: none;
}

.admin-error-message.admin-visible {
    display: block;
}

.admin-success-message {
    background: #d1fae5;
    color: #065f46;
    padding: 12px 16px;
    border-radius: 6px;
    margin-bottom: 20px;
    display: none;
}

.admin-success-message.admin-visible {
    display: block;
}

.admin-modal {
    display: none;
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.5);
    z-index: 1000;
    align-items: center;
    justify-content: center;
}

.admin-modal.active {
    display: flex;
}

.admin-modal__content {
    background: var(--bg-secondary, #ffffff);
    border-radius: 8px;
    padding: 24px;
    max-width: 600px;
    width: 90%;
    max-height: 90vh;
    overflow-y: auto;
    box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1);
}

.admin-modal__header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;
}

.admin-modal__header h2 {
    margin: 0;
    font-size: 20px;
    color: var(--text-primary, #111827);
}

.admin-modal__close {
    background: none;
    border: none;
    font-size: 24px;
    cursor: pointer;
    color: var(--text-secondary, #6b7280);
    padding: 0;
    width: 32px;
    height: 32px;
}

.admin-modal__close:hover,
.admin-modal__close:focus-visible {
    color: var(--text-primary, #111827);
}

.admin-modal__close:focus-visible {
    outline: 2px solid var(--accent-color, #3b82f6);
    outline-offset: 2px;
}

.admin-action-btn--danger {
    color: var(--admin-danger);
    border-color: color-mix(in srgb, var(--admin-danger) 60%, transparent);
}

.admin-action-btn:disabled {
    opacity: 0.5;
    cursor: default;
}

.admin-deletion-note {
    margin-top: 4px;
    font-size: 12px;
    color: var(--admin-danger);
}

/* Store listings (S-10 FR-11) */
.admin-listings-filter select {
    padding: 4px 8px;
    border: 1px solid var(--border-color, #d1d5db);
    border-radius: 4px;
    background: var(--bg-primary);
    color: var(--text-primary);
}

.admin-visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

/* Image review (S-10 FR-8) */
.admin-section__hint {
    margin: 0 0 16px;
    font-size: 13px;
    color: var(--text-secondary);
}

.admin-held-images {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 16px;
}

.admin-held-image {
    border: 1px solid var(--border-color, #e5e7eb);
    border-radius: 8px;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

.admin-held-image__frame {
    display: block;
    width: 100%;
    aspect-ratio: 4 / 3;
    padding: 0;
    border: 0;
    background: var(--bg-tertiary);
    cursor: pointer;
    overflow: hidden;
}

.admin-held-image__frame img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    transition: filter 0.15s ease;
}

.admin-held-image__frame.is-blurred img {
    filter: blur(24px);
}

.admin-held-image__frame:focus-visible {
    outline: 2px solid var(--accent-color, #3b82f6);
    outline-offset: -2px;
}

.admin-held-image__body {
    padding: 12px;
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.admin-held-image__body p {
    margin: 0;
    overflow-wrap: anywhere;
}

/* Reports (S-53 FR-9, FR-10) */
.admin-reports {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.admin-report {
    border: 1px solid var(--border-color, #e5e7eb);
    border-radius: 8px;
    padding: 16px;
}

.admin-report.is-resolved {
    opacity: 0.7;
}

.admin-report__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 12px;
    color: var(--text-primary, #111827);
}

.admin-report__meta {
    margin-left: auto;
    font-size: 12px;
    color: var(--text-secondary, #6b7280);
}

.admin-report__note {
    margin: 10px 0 0;
    white-space: pre-wrap;
    color: var(--text-primary, #111827);
}

.admin-report__warning {
    padding: 8px 10px;
    border-left: 3px solid var(--admin-danger);
    background: color-mix(in srgb, var(--admin-danger) 10%, transparent);
}

.admin-section-error {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
}

.admin-report__excerpt {
    margin: 12px 0 0;
    padding: 10px 12px;
    border-left: 3px solid var(--border-color, #d1d5db);
    background: var(--bg-tertiary, #fafafa);
    font-size: 13px;
    max-height: 260px;
    overflow-y: auto;
}

.admin-report__line {
    margin: 0 0 6px;
    white-space: pre-wrap;
    word-break: break-word;
    color: var(--text-primary, #111827);
}

.admin-report__line.is-reported strong {
    color: var(--admin-danger);
}

.admin-report__line.is-the-message {
    background: var(--accent-accent-20);
    border-radius: 4px;
    padding: 4px 6px;
    margin-left: -6px;
}

.admin-report__flag {
    margin-left: 6px;
    padding: 0 6px;
    border-radius: 8px;
    background: #fee2e2;
    color: #991b1b;
    font-size: 10px;
    font-weight: 600;
    text-transform: uppercase;
}

.admin-report__original {
    color: var(--text-primary, #111827);
    font-style: italic;
}

.admin-report__time {
    color: var(--text-secondary, #6b7280);
    font-size: 11px;
    margin-left: 6px;
}

.admin-report__resolution {
    margin: 10px 0 0;
    font-size: 12px;
    color: var(--text-secondary, #6b7280);
}

.admin-report__actions {
    display: flex;
    justify-content: flex-end;
    margin-top: 12px;
}

/* Responsive */
@media (max-width: 768px) {
    .admin-form-grid {
        grid-template-columns: 1fr;
    }

    .admin-header {
        flex-direction: column;
        align-items: flex-start;
    }
}

/* Activity log */
.admin-audit-table td {
    font-size: 13px;
    padding: 10px 16px;
}

.admin-audit-what {
    font-weight: 600;
    white-space: nowrap;
}

.admin-audit-row--failed .admin-audit-what {
    color: var(--admin-danger);
}

.admin-audit-ip {
    font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
    color: var(--text-secondary);
}

/* Explicit areas: hidden sections must stay hidden regardless of shared layouts. */
.admin-page section[hidden] { display: none !important; }

/* Landing page: queue cards (lit only when something waits), then a Manage row. */
.admin-overview__title {
    margin: 0 0 12px;
    font-size: 13px;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--text-secondary);
}
.admin-overview__title:not(:first-child) { margin-top: 36px; }
.admin-overview__loading { color: var(--text-secondary); }
.admin-plan-term--warn { color: var(--admin-danger); }
.admin-back {
    margin: 0 0 16px;
    padding: 8px 14px;
    font-size: 14px;
    color: var(--text-primary);
    background: transparent;
    border: 1px solid var(--border-color);
    border-radius: 6px;
    cursor: pointer;
}
.admin-back:hover { border-color: var(--accent-color); }
.admin-back:focus-visible { outline: 2px solid var(--accent-color); outline-offset: 2px; }
.admin-queue-cards,
.admin-manage-cards {
    display: grid;
    gap: 16px;
    list-style: none;
    padding: 0;
    margin: 0;
}
.admin-queue-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.admin-manage-cards { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.admin-queue-card,
.admin-manage-card {
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
    text-align: left;
    color: var(--text-primary);
    background: var(--bg-secondary);
    border: 1px solid var(--border-color);
    border-radius: 10px;
    cursor: pointer;
    transition: border-color .15s, transform .15s, background .15s;
}
.admin-queue-card { padding: 22px 24px; }
.admin-manage-card { padding: 16px 18px; }
.admin-queue-card:hover,
.admin-manage-card:hover { border-color: var(--accent-color); transform: translateY(-1px); }
.admin-queue-card:focus-visible,
.admin-manage-card:focus-visible { outline: 2px solid var(--accent-color); outline-offset: 2px; }
.admin-queue-card__count {
    font-size: 40px;
    line-height: 1;
    font-weight: 700;
    color: var(--text-secondary);
    opacity: .6;
}
.admin-queue-card__title { font-size: 16px; font-weight: 600; }
.admin-queue-card__hint,
.admin-manage-card__hint { font-size: 13px; color: var(--text-secondary); }
.admin-manage-card__name { font-size: 15px; font-weight: 600; }
.admin-queue-card--waiting {
    border-color: color-mix(in srgb, var(--accent-color) 55%, transparent);
    background: color-mix(in srgb, var(--accent-color) 10%, var(--bg-secondary));
}
.admin-queue-card--waiting .admin-queue-card__count { color: var(--accent-color); opacity: 1; }
.admin-queue-card--reports.admin-queue-card--waiting {
    border-color: color-mix(in srgb, var(--admin-danger) 55%, transparent);
    background: color-mix(in srgb, var(--admin-danger) 10%, var(--bg-secondary));
}
.admin-queue-card--reports.admin-queue-card--waiting .admin-queue-card__count { color: var(--admin-danger); }
@media (max-width: 900px) {
    .admin-manage-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.admin-users-search, .admin-pager { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin: 16px 0; }
.admin-users-search input { flex: 1; min-width: 180px; padding: 10px; }
.admin-section__header { flex-wrap: wrap; gap: 12px; }
.admin-listings-filter select { max-width: 100%; padding: 8px; }
.admin-storage--near { background: color-mix(in srgb, #e9b949 15%, transparent); font-weight: 600; }
#storage-scan-result p { padding: 12px; overflow-wrap: anywhere; }
.admin-action-btn:disabled { opacity: .5; cursor: default; }
.admin-nav { flex-wrap: wrap; }
@media (max-width: 600px) {
    .admin-container { padding: 24px 16px; }
    .admin-queue-cards, .admin-manage-cards { grid-template-columns: minmax(0, 1fr); }
    .admin-nav { width: 100%; gap: 12px; }
}

/* Portal workspace: quiet surfaces and consistent controls, separate from login. */
.admin-portal {
    --bg-primary: #0d141f;
    --bg-secondary: #151f2d;
    --bg-tertiary: #192433;
    --text-primary: #e9eef5;
    --text-secondary: #a4b1c2;
    --border-color: #2a3748;
    --accent-color: #b8caa2;
    --bg-hover: #233144;
    padding-top: 0;
    background: var(--bg-primary);
    font-family: Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
}
.admin-portal .admin-container { padding: 0 40px 64px; }
.admin-portal .admin-header { min-height: 100px; padding: 22px 0; margin-bottom: 40px; border-bottom: 1px solid var(--border-color); }
.admin-brand { display: flex; gap: 13px; align-items: center; }
.admin-brand__mark { display: grid; place-items: center; width: 38px; height: 42px; border: 1px solid #708563; border-radius: 9px; color: #d1dfba; font: 26px Georgia, serif; }
.admin-brand__name { font-size: 10px; letter-spacing: .18em; color: var(--text-secondary); }
.admin-portal .admin-header h1 { font-size: 17px; font-weight: 600; letter-spacing: -.02em; margin-top: 3px; }
.admin-portal .admin-nav { gap: 8px; }
.admin-portal .admin-nav button, .admin-portal .admin-nav a { display: inline-flex; align-items: center; justify-content: center; min-height: 36px; padding: 8px 12px; border: 1px solid transparent; border-radius: 6px; background: transparent; color: var(--text-secondary); font: inherit; font-size: 12px; box-shadow: none; }
.admin-portal .admin-nav button:hover, .admin-portal .admin-nav a:hover { background: var(--bg-hover); color: var(--text-primary); }
.admin-portal .admin-nav #admin-home[aria-current="page"] { border-color: var(--border-color); color: var(--text-primary); background: var(--bg-secondary); }
.admin-portal .admin-nav__username { font-size: 12px; padding-right: 12px; margin-right: 4px; border-right: 1px solid var(--border-color); }
.admin-overview__intro { margin: 0 0 38px; }
.admin-eyebrow { font-size: 10px; font-weight: 600; letter-spacing: .16em; color: var(--accent-color); }
.admin-overview__intro h2 { font-size: 34px; font-weight: 600; letter-spacing: -.035em; margin: 8px 0; color: var(--text-primary); }
.admin-overview__intro p { font-size: 14px; margin: 0; color: var(--text-secondary); }
.admin-overview__section-title { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; margin-bottom: 14px; }
.admin-overview__section-title h3 { margin: 0; font-size: 14px; font-weight: 600; color: var(--text-primary); }
.admin-overview__section-title > span { font-size: 12px; color: var(--text-secondary); }
.admin-overview__section-title--manage { margin-top: 36px; }
.admin-portal .admin-queue-cards { gap: 16px; }
.admin-portal .admin-queue-card { position: relative; padding: 24px; min-height: 178px; gap: 8px; border: 1px solid var(--border-color); border-radius: 10px; background: var(--bg-secondary); box-shadow: 0 4px 16px #00000012; }
.admin-portal .admin-queue-card::after { content: '↗'; position: absolute; top: 22px; right: 24px; font-size: 20px; color: var(--text-secondary); }
.admin-portal .admin-queue-card__count { font-size: 38px; font-weight: 500; letter-spacing: -.04em; margin-bottom: 8px; line-height: 1; color: var(--text-secondary); opacity: 1; }
.admin-portal .admin-queue-card--waiting .admin-queue-card__count { color: #e4d0a6; }
.admin-portal .admin-queue-card--reports.admin-queue-card--waiting .admin-queue-card__count { color: #e9ab9f; }
.admin-portal .admin-queue-card__title { font-size: 14px; font-weight: 600; }
.admin-portal .admin-queue-card__hint { font-size: 12px; line-height: 1.6; }
.admin-portal .admin-manage-cards { grid-template-columns: repeat(2, minmax(0,1fr)); gap: 12px; }
.admin-portal .admin-manage-card { display: grid; grid-template-columns: 40px 1fr 16px; gap: 4px 16px; padding: 20px; background: transparent; border-radius: 9px; }
.admin-manage-card__icon { grid-column: 1; grid-row: 1 / 3; align-self: center; width: 40px; height: 40px; display: grid; place-items: center; background: var(--bg-secondary); border-radius: 8px; color: #b1c4cf; }
.admin-manage-card__icon svg { width: 21px; height: 21px; }
.admin-portal .admin-manage-card__name, .admin-portal .admin-manage-card__hint { grid-column: 2; }
.admin-portal .admin-manage-card__name { font-size: 14px; }
.admin-portal .admin-manage-card__hint { font-size: 12px; line-height: 1.5; }
.admin-portal .admin-manage-card::after { content: '›'; grid-column: 3; grid-row: 1 / 3; align-self: center; color: var(--text-secondary); font-size: 22px; }
.admin-portal .admin-queue-card:hover, .admin-portal .admin-manage-card:hover { border-color: #63758b; background: #1b2838; transform: none; }
.admin-portal .admin-section__header { justify-content: flex-start; gap: 12px; background: var(--bg-secondary); }
.admin-portal .admin-section__header h2 { margin-right: auto; }
.admin-portal .admin-user-count { font-size: 12px; }
.admin-portal .admin-listings-filter { margin: 0; }
.admin-portal input, .admin-portal select { color: var(--text-primary); background: var(--bg-primary); border-color: var(--border-color); border-radius: 6px; }
.admin-portal .admin-back { margin-bottom: 24px; border: 0; padding-left: 0; background: transparent; color: var(--text-secondary); }
.admin-portal .admin-back:hover { color: var(--text-primary); }
@media (max-width: 900px) {
    .admin-portal .admin-header { gap: 20px; }
    .admin-portal .admin-nav { margin-left: auto; }
    .admin-portal .admin-container { padding-inline: 24px; }
}
@media (max-width: 600px) {
    .admin-portal .admin-container { padding: 0 20px 36px; }
    .admin-portal .admin-header { margin-bottom: 28px; }
    .admin-portal .admin-nav { gap: 4px; }
    .admin-portal .admin-nav__username { width: 100%; border: 0; padding: 0 0 6px; }
    .admin-portal .admin-nav button, .admin-portal .admin-nav a { padding: 8px; }
    .admin-overview__intro { margin-bottom: 28px; }
    .admin-overview__intro h2 { font-size: 29px; }
    .admin-overview__section-title { flex-direction: column; gap: 5px; }
    .admin-portal .admin-manage-cards { grid-template-columns: minmax(0,1fr); }
    .admin-portal .admin-queue-card { min-height: 150px; }
    .admin-portal .admin-section__header h2 { width: 100%; }
}
.admin-portal { padding: 0; }
@media (max-width: 600px) {
    .admin-portal .admin-nav { display: grid; grid-template-columns: repeat(4, auto); justify-content: start; }
    .admin-portal .admin-nav__username { grid-column: 1 / -1; }
    .admin-portal .admin-nav button, .admin-portal .admin-nav a { font-size: 11px; padding: 8px 6px; }
}


/* pages/_library-pages.css */
/* Opt-in library presentation. Theme tokens remain the source of every color. */
body.library-page {
    --shadow-primary-10: color-mix(in srgb, var(--primary-color) 10%, transparent);
    --shadow-primary-20: color-mix(in srgb, var(--primary-color) 20%, transparent);
    --accent-primary-10: color-mix(in srgb, var(--primary-color) 10%, transparent);
    background: var(--surface-base);
    color: var(--text-light);
    padding: 0;
}

.library-page .top-nav-bar {
    position: sticky;
    top: 0;
    padding: 22px 24px 18px;
    gap: 12px;
    flex-wrap: wrap;
    background: var(--surface-base);
    border-bottom: 1px solid var(--border-color);
    box-shadow: 0 5px 20px var(--shadow-primary-10);
}

.library-page .top-nav-title {
    flex-basis: 100%;
    font-family: Georgia, 'Times New Roman', serif;
    font-size: 28px;
    font-weight: 500;
    color: var(--text-light);
}

.library-page .top-nav-search { flex: 1 1 220px; max-width: none; }
body.library-page.characters-page .top-nav-bar { padding: 22px 24px 18px !important; }
.library-page .top-nav-actions { flex-wrap: wrap; gap: 8px; }
.library-page .top-nav-bar :is(input, select) {
    min-height: 38px;
    padding: 9px 12px;
    font-size: 14px;
    border: 1px solid var(--border-color);
    border-radius: 6px;
    background: var(--surface-panel);
    color: var(--text-light);
}
.library-page #type-filter-container { padding: 0; border: 0; background: none; }
.library-page .content-wrapper { padding: 20px 24px 28px; }
.library-page .item-grid { margin-top: 0; }
.library-page .form-list-container {
    border: 1px solid var(--border-color);
    border-radius: 10px;
    background: var(--surface-panel);
    overflow: hidden;
}
.library-page .form-list-item {
    padding: 16px;
    gap: 16px;
    background: transparent;
    border: 0;
    border-bottom: 1px solid color-mix(in srgb, var(--border-color) 55%, transparent);
    border-radius: 0;
    box-shadow: none;
    transition: background .18s ease, box-shadow .18s ease;
}
.library-page .form-list-item:hover {
    transform: none;
    background: var(--accent-primary-10);
    box-shadow: inset 3px 0 var(--primary-color);
}
.library-page .form-list-item:last-child { border-bottom: 0; }
.library-page .form-list-content { min-width: 0; }
.library-page .form-list-name { font-size: 16px; line-height: 1.4; color: var(--text-light); }
.library-page .form-list-header { gap: 10px; margin-bottom: 5px; }
.library-page .form-list-description { font-size: 14px; line-height: 1.5; opacity: 1; }
.library-page :is(.form-list-meta, .form-list-summary) {
    font-family: inherit;
    font-size: 12px;
    line-height: 1.5;
    opacity: 1;
    color: var(--secondary-color);
    flex-wrap: wrap;
    margin-top: 5px;
}
.library-page .form-list-badge {
    font-size: 12px;
    padding: 3px 8px;
    border-radius: 5px;
    color: var(--text-light);
    background: var(--accent-primary-10);
    border: 1px solid var(--border-color);
    text-transform: none;
    letter-spacing: normal;
}
.library-page .form-list-thumbnail :is(img, .no-image) {
    width: 64px;
    height: 64px;
    border: 1px solid var(--border-color);
    border-radius: 7px;
    background: var(--surface-base);
    color: var(--text-light);
    font-size: 12px;
}
.library-page .form-list-actions { gap: 8px; }
.library-page .btn {
    min-height: 36px;
    padding: 8px 12px;
    border-radius: 6px;
    font-size: 13px;
    font-weight: 500;
    border: 1px solid var(--border-color);
    background: var(--surface-panel);
    color: var(--text-light);
    box-shadow: none;
    transform: none;
}
.library-page .btn:hover {
    border-color: var(--primary-color);
    box-shadow: 0 0 12px var(--shadow-primary-20);
    transform: none;
}
.library-page .btn-primary,
.library-page form button[type="submit"] {
    background: var(--primary-color);
    border-color: var(--primary-color);
    color: var(--surface-base);
    font-weight: 600;
}
.library-page .btn-danger { color: var(--danger-color); }
.library-page .form-list-actions .btn { min-width: 36px; padding: 8px; }
.library-page .modal { background: color-mix(in srgb, var(--surface-base) 65%, transparent); }
.library-page .modal .modal-content {
    background: var(--surface-base);
    color: var(--text-light);
    border: 1px solid var(--border-color);
    border-radius: 12px;
    padding: 24px;
    box-shadow: 0 10px 40px var(--shadow-primary-20);
}
.library-page .modal #modal-title {
    text-align: left;
    background: none;
    text-shadow: none;
    font-family: Georgia, 'Times New Roman', serif;
    font-size: 25px;
    font-weight: 500;
    color: var(--text-light);
    margin: 0 0 24px;
    padding-bottom: 16px;
    border-bottom: 1px solid var(--border-color);
}
.library-page .modal.trading-card-modal .modal-content::before { content: none; }
.library-page .modal.trading-card-modal :is(#item-form, #spell-form) { padding: 0; gap: 0; }
.library-page .modal.trading-card-modal form .form-group {
    margin-bottom: 20px;
    padding: 0;
    background: transparent !important;
    border: 0 !important;
    box-shadow: none;
}
.library-page .modal form .form-group > label {
    text-transform: none;
    letter-spacing: normal;
    text-shadow: none;
    color: var(--text-light);
    font-size: 14px;
    margin-bottom: 8px;
    line-height: 1.5;
}
/* IDs match the existing dense edit-form rules without touching character sheets. */
.library-page .modal :is(#item-form, #spell-form) :is(input:not([type="checkbox"]):not([type="radio"]), select, textarea) {
    background: var(--surface-panel) !important;
    border: 1px solid var(--border-color) !important;
    border-radius: 6px;
    color: var(--text-light);
    padding: 11px 12px;
    font-size: 14px;
    line-height: 1.5;
    max-width: 100%;
}
.library-page .modal :is(#item-form, #spell-form) textarea { min-height: 110px; }
.library-page :is(input, select, textarea, button):focus-visible {
    outline: 2px solid var(--primary-color);
    outline-offset: 2px;
    box-shadow: 0 0 12px var(--shadow-primary-20);
}
.library-page .modal :is(small, .form-hint) { font-size: 12px; line-height: 1.5; opacity: 1; }
.library-page .modal .form-action-row {
    padding-top: 18px;
    border-top: 1px solid var(--border-color);
    gap: 10px;
}
@media (max-width: 600px) {
    .library-page .top-nav-bar { padding: 16px; }
    .library-page .content-wrapper { padding: 16px; }
    .library-page .top-nav-actions { flex-basis: 100%; }
    .library-page .form-list-item { gap: 10px; padding: 12px; flex-wrap: wrap; }
    .library-page .form-list-content { flex: 1 1 160px; }
    .library-page .form-list-actions { margin-left: auto; }
    .library-page .modal .modal-content { padding: 18px; width: calc(100% - 24px); }
}


/* pages/_character-editor.css */
/* Character/NPC edit dialogs only; the character sheets and combat stay separate. */
.character-editor.modal.trading-card-modal .modal-content {
    width: calc(100% - 32px);
    max-width: 880px;
    padding: 24px;
    background: var(--surface-base);
    color: var(--text-light);
    border: 1px solid var(--border-color);
    border-radius: 12px;
    box-shadow: 0 12px 40px var(--shadow-primary-25);
}
.character-editor.modal { background: color-mix(in srgb, var(--surface-base) 65%, transparent); }
.character-editor.modal .modal-content::before { content: none; }
.character-editor.modal #modal-title {
    padding: 0 0 16px;
    margin: 0 0 20px;
    text-align: left;
    font: 500 26px Georgia, 'Times New Roman', serif;
    color: var(--text-light);
    background: none;
    text-shadow: none;
    border-bottom: 1px solid var(--border-color);
}
.character-editor.modal #item-form { padding: 0; gap: 20px; }
.character-editor.modal #item-form > div:not(.form-group) { gap: 12px !important; }
.character-editor.modal #item-form #image-preview img { max-height: 130px; max-width: 100%; width: auto; object-fit: contain; }
.character-editor.modal #item-form > div:first-of-type:not(.form-group) {
    grid-template-columns: 2fr 1.2fr .7fr 1fr;
}
.character-editor.modal #item-form > div:first-of-type:has(#item-challenge-rating) {
    grid-template-columns: repeat(4, minmax(0, 1fr));
}
.character-editor.modal #item-form > div:first-of-type:has(#item-challenge-rating) > .form-group:first-child { grid-column: 1 / -1; }
.character-editor.modal #item-form .form-group {
    min-width: 0;
    padding: 0;
    background: transparent !important;
    border: 0 !important;
    box-shadow: none;
}
.character-editor.modal #item-form .form-group > label:first-child {
    font-size: 14px;
    line-height: 1.5;
    margin-bottom: 8px;
    color: var(--text-light);
    text-transform: none;
    letter-spacing: normal;
    text-shadow: none;
}
.character-editor.modal #item-form .form-group label {
    font-size: 12px;
    color: var(--text-light);
    text-shadow: none;
}
/* Old density rules contain multiple IDs and !important; keep overrides local. */
.character-editor.modal #item-form :is(input:not([type="checkbox"]):not([type="radio"]):not([type="hidden"]), select, textarea) {
    min-width: 0;
    max-width: 100%;
    min-height: 38px;
    padding: 9px 10px !important;
    font-size: 14px !important;
    line-height: 1.4;
    background: var(--surface-panel) !important;
    border: 1px solid var(--border-color) !important;
    color: var(--text-light);
    border-radius: 6px !important;
}
.character-editor.modal #item-form input[type="number"] { padding-right: 24px !important; }
.character-editor.modal #item-form textarea { min-height: 100px; }
.character-editor.modal #item-form .form-group > div:has(#item-str),
.character-editor.modal #item-form .form-group > div:has(#item-base-ac) {
    gap: 10px !important;
    margin-top: 10px;
    grid-template-columns: repeat(auto-fit, minmax(90px, 1fr));
}
.character-editor.modal #item-form .form-group:has(#item-str),
.character-editor.modal #item-form .form-group:has(#skill-acrobatics) {
    padding: 16px;
    background: var(--surface-panel) !important;
    border: 1px solid var(--border-color) !important;
    border-radius: 8px;
}
.character-editor.modal #item-form .form-group > div:has(#skill-acrobatics) {
    font-size: 13px;
    gap: 8px;
    max-height: 220px;
    background: transparent;
}
.character-editor.modal #item-form :is(small, .form-hint) { font-size: 12px; line-height: 1.5; }
.character-editor.modal #item-form .btn {
    min-height: 36px;
    padding: 8px 12px;
    font-size: 13px;
    background: var(--surface-panel);
    color: var(--text-light);
    border: 1px solid var(--border-color);
    border-radius: 6px;
    transform: none;
}
.character-editor.modal #item-form button[type="submit"] {
    background: var(--primary-color);
    border-color: var(--primary-color);
    color: var(--surface-base);
    font-weight: 600;
}
.character-editor.modal #item-form .modal-actions {
    gap: 10px;
    padding-top: 16px;
    border-top: 1px solid var(--border-color);
}
.character-editor.modal :is(input, select, textarea, button):focus-visible {
    outline: 2px solid var(--primary-color);
    outline-offset: 2px;
    box-shadow: 0 0 12px var(--shadow-primary-25);
}
@media (max-width: 650px) {
    .character-editor.modal.trading-card-modal .modal-content { padding: 18px; }
    .character-editor.modal #item-form > div:not(.form-group),
    .character-editor.modal #item-form > div:first-of-type:has(#item-challenge-rating) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .character-editor.modal #item-form > div:first-of-type > .form-group:first-child { grid-column: 1 / -1; }
    .character-editor.modal #item-form .form-group > div:has(#item-str) { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}


/* components/_condition-icons.css */
/* Small engraved-style condition symbols: colored ink, no emoji or backgrounds. */
.condition-glyph {
    width: 1.15em;
    height: 1.15em;
    min-width: 18px;
    min-height: 18px;
    display: inline-block;
    vertical-align: middle;
    flex-shrink: 0;
    color: var(--secondary-color);
}
.condition-glyph--blinded, .condition-glyph--invisible, .condition-glyph--unconscious {
    color: color-mix(in srgb, #8d9fbc 70%, var(--text-light));
}
.condition-glyph--charmed, .condition-glyph--frightened {
    color: color-mix(in srgb, #b491ad 70%, var(--text-light));
}
.condition-glyph--grappled, .condition-glyph--restrained, .condition-glyph--exhaustion {
    color: color-mix(in srgb, #b69a71 70%, var(--text-light));
}
.condition-glyph--poisoned { color: color-mix(in srgb, #8ea477 70%, var(--text-light)); }
.condition-glyph--paralyzed, .condition-glyph--stunned { color: color-mix(in srgb, #c1a56f 70%, var(--text-light)); }
.condition-glyph--incapacitated { color: color-mix(in srgb, #bd8581 70%, var(--text-light)); }


/* pages/_detail-sheet.css */
/* Shared character/NPC sheet presentation; all interactions remain in the renderers. */
body:has(> #character-detail-container) { background: var(--surface-base); }
#character-detail-container:has(> .detail-sheet) { padding: 0 !important; }
.detail-sheet {
    padding: 24px !important;
    color: var(--text-light) !important;
    font-size: 14px;
    line-height: 1.5;
}
.detail-sheet .detail-sheet-header {
    padding-bottom: 18px !important;
    border-bottom: 1px solid var(--border-color) !important;
    gap: 16px;
    flex-wrap: wrap;
}
.detail-sheet-header h2 {
    font: 500 30px Georgia, 'Times New Roman', serif;
    color: var(--text-light) !important;
    overflow-wrap: anywhere;
}
.detail-sheet .detail-sheet-overview {
    width: 100%;
    grid-template-columns: repeat(3, minmax(0, 1fr)) minmax(180px, 1.15fr) !important;
    gap: 16px !important;
    align-items: start !important;
}
.detail-sheet-overview > div { min-width: 0; height: auto !important; }
.detail-sheet .detail-sheet-panel { height: auto !important; flex-grow: 0 !important; }
.detail-sheet .detail-sheet-overview:has(> .detail-sheet-portrait:nth-child(3)) {
    grid-template-columns: repeat(2, minmax(0, 1fr)) minmax(200px, 1.2fr) !important;
}
.detail-sheet .detail-sheet-panel,
.detail-sheet :is(.npc-combat-panel, .npc-abilities-container) {
    background: var(--surface-panel) !important;
    border: 1px solid var(--border-color) !important;
    border-radius: 10px !important;
    padding: 16px !important;
    box-shadow: 0 4px 18px color-mix(in srgb, var(--primary-color) 8%, transparent);
}
.detail-sheet-overview > div > div > div[style*="background"]:not(.detail-sheet-panel),
.detail-sheet .npc-level-panel,
.detail-sheet :is(.npc-stat-row, .npc-stat-row-simple, .npc-stat-row-glow, .npc-info-row, .npc-ability-row, .npc-cr-panel, .npc-ac-row) {
    background: transparent !important;
    border-left: 0 !important;
    border-radius: 0 !important;
    border-bottom: 1px solid var(--border-color) !important;
    box-shadow: none !important;
    padding: 9px 0 !important;
    margin-bottom: 0;
}
.detail-sheet-overview [style*="space-around"] { justify-content: flex-start !important; gap: 8px; }
.detail-sheet-overview [style*="font-size: 0."] { font-size: 12px !important; }
.detail-sheet-overview span[style*="font-weight: 600"] { font-size: 16px !important; }
.detail-sheet-overview [style*="border-left: 2px"] {
    border-left: 0 !important;
    background: transparent !important;
    border-bottom: 1px solid var(--border-color) !important;
    border-radius: 0 !important;
    padding: 9px 0 !important;
}
.detail-sheet-overview [style*="opacity: 0.6"] { opacity: 1 !important; }
.detail-sheet-overview strong,
.detail-sheet :is(.npc-info-label, .npc-combat-panel-title, .npc-cr-label) { color: var(--text-light) !important; font-size: 12px; }
.detail-sheet :is(.npc-info-value, .npc-stat-value, .npc-ability-name, .npc-ability-score, .npc-ability-modifier) { font-size: 14px; }
.detail-sheet .detail-sheet-portrait { width: 100% !important; min-width: 0 !important; }
.detail-sheet-portrait > div:first-child { max-width: 100% !important; }
.detail-sheet-portrait > div:first-child > :is(img, div) {
    width: 100% !important;
    max-width: 100% !important;
    height: auto !important;
    min-height: 180px;
    max-height: 420px;
    object-fit: contain;
    background: var(--surface-panel) !important;
    border: 1px solid var(--border-color) !important;
    border-radius: 10px !important;
    box-shadow: 0 0 24px var(--shadow-primary-25) !important;
}
.detail-sheet button {
    min-height: 34px;
    padding: 7px 11px;
    font-family: inherit;
    font-weight: 500;
    line-height: 1.3;
    font-size: 13px !important;
    background: var(--surface-panel) !important;
    color: var(--text-light) !important;
    border: 1px solid var(--border-color) !important;
    border-radius: 6px;
    transform: none !important;
}
.detail-sheet button:hover { border-color: var(--primary-color) !important; box-shadow: 0 0 10px var(--shadow-primary-25); }
.detail-sheet button:focus-visible { outline: 2px solid var(--primary-color); outline-offset: 2px; }
.detail-sheet .edit-item-btn { background: var(--primary-color) !important; color: var(--surface-base) !important; }
.detail-sheet .detail-tab-container { gap: 6px; flex-wrap: wrap; padding-bottom: 10px; border-bottom: 1px solid var(--border-color); }
.detail-sheet .detail-tab-btn { padding: 10px 16px; }
.detail-sheet .detail-tab-btn.active { background: var(--accent-primary-20) !important; border-color: var(--primary-color) !important; }
.detail-sheet .detail-tab-content { line-height: 1.65; }
.detail-sheet .detail-tab-content [style*="background: rgba(27, 42, 106"],
.detail-sheet .detail-tab-content :is(.spell-item, .inventory-item, .feature-item) {
    background: var(--surface-panel) !important;
    border-color: var(--border-color) !important;
    border-radius: 8px !important;
}
.detail-sheet .detail-tab-content [style*="font-size: 0."] { font-size: 13px !important; }
.detail-sheet .detail-saves-panel { height: auto !important; flex: 0 0 auto !important; }
.detail-sheet .detail-save-rows { gap: 0; flex: 0 0 auto !important; }
.detail-sheet .detail-save-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 9px 0;
    border-bottom: 1px solid var(--border-color);
}
.detail-sheet .detail-save-row:last-child { border-bottom: 0; }
.detail-sheet .detail-save-label { font-size: 13px; }
.detail-sheet .detail-save-abbr { color: var(--text-light); opacity: 0.75; font-size: 12px; white-space: nowrap; }
.detail-sheet .detail-save-value { color: var(--primary-color); font-size: 16px; font-weight: 600; font-variant-numeric: tabular-nums; }
.detail-sheet .save-proficiency-badge {
    display: block;
    width: fit-content;
    margin-top: 3px;
    padding: 1px 6px;
    border-radius: 4px;
    background: var(--accent-primary-20);
    color: var(--text-light);
    font-size: 12px;
}
@media (max-width: 950px) {
    .detail-sheet .detail-sheet-overview,
    .detail-sheet .detail-sheet-overview:has(> .detail-sheet-portrait:nth-child(3)) { grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
}
@media (max-width: 520px) {
    .detail-sheet { padding: 16px !important; }
    .detail-sheet .detail-sheet-overview,
    .detail-sheet .detail-sheet-overview:has(> .detail-sheet-portrait:nth-child(3)) { grid-template-columns: minmax(0, 1fr) !important; }
    .detail-sheet-header > div { flex-wrap: wrap; }
}

/* Read-only enlarged artwork, independent of edit permissions. */
.detail-portrait-expand { cursor: zoom-in; }
.detail-portrait-expand:focus-visible { outline: 2px solid var(--primary-color); outline-offset: 4px; }
.detail-portrait-dialog { width: min(1100px, 94vw); max-height: 94vh; padding: 16px; border: 1px solid var(--primary-color); border-radius: 12px; background: var(--surface-base); color: var(--text-light); box-shadow: 0 0 32px var(--shadow-primary-25); }
.detail-portrait-dialog::backdrop { background: rgb(0 0 0 / 80%); }
.detail-portrait-dialog img { display: block; width: 100%; height: auto; max-height: 80vh; object-fit: contain; margin-top: 12px; }
.detail-portrait-dialog button { padding: 9px 14px; border: 1px solid var(--border-color); border-radius: 6px; background: var(--surface-panel); color: var(--text-light); cursor: pointer; }
.detail-portrait-dialog .detail-portrait-report { margin-top: 12px; }

/* Keep wizard presentation isolated from the shared modal and library styles. */
#level-up-wizard-modal .level-up-wizard-content { width: min(820px, 94vw); max-width: 820px; background: var(--surface-base); color: var(--text-light); border: 1px solid var(--border-color); border-radius: 12px; box-shadow: 0 0 28px var(--shadow-primary-25); overflow: hidden; font-size: 14px; line-height: 1.6; }
#level-up-wizard-modal :is(.level-up-wizard-header, .level-up-wizard-footer) { padding: 18px 24px; background: var(--surface-panel); border-color: var(--border-color); border-width: 1px; }
#level-up-wizard-modal .level-up-wizard-title { margin: 0 0 10px; font: 500 26px Georgia, serif; color: var(--text-light); }
#level-up-wizard-modal .level-up-wizard-body { padding: 24px; }
#level-up-wizard-modal h3 { margin: 0 0 18px; font-size: 20px; color: var(--text-light); }
#level-up-wizard-modal h4 { margin: 0 0 10px; font-size: 15px; color: var(--text-light); }
#level-up-wizard-modal :is(.character-info, .progression-preview, .feature-item, .ability-score-item, .asi-summary, .proficiency-bonus-update, .hit-dice-increase-section, .hp-increase-result, .hit-dice-info, .summary-section, .spell-slots-current, .spell-slots-new) { padding: 16px; margin-bottom: 14px; background: var(--surface-panel); border: 1px solid var(--border-color); border-radius: 8px; box-shadow: none; }
#level-up-wizard-modal :is(p, li, label, .feature-description) { font-size: 14px; line-height: 1.6; }
#level-up-wizard-modal .wizard-progress { height: 26px; border-radius: 5px; background: var(--surface-base); }
#level-up-wizard-modal .wizard-progress-bar { border-radius: 4px; background: var(--accent-primary-20); }
#level-up-wizard-modal .wizard-progress-text { font-size: 12px; color: var(--text-light); text-shadow: none; }
#level-up-wizard-modal button { min-height: 36px; border-radius: 6px; font-size: 14px; padding: 8px 14px; background: var(--surface-panel); color: var(--text-light); border: 1px solid var(--border-color); box-shadow: none; }
#level-up-wizard-modal button:hover:not(:disabled) { border-color: var(--primary-color); box-shadow: 0 0 10px var(--shadow-primary-25); }
#level-up-wizard-modal button:disabled { opacity: .45; cursor: not-allowed; }
#level-up-wizard-modal :is(input:not([type=checkbox]):not([type=radio]), select, textarea) { background: var(--surface-base); color: var(--text-light); border: 1px solid var(--border-color); border-radius: 6px; min-height: 36px; font-size: 14px; }
#level-up-wizard-modal :is(button, input, select, textarea):focus-visible { outline: 2px solid var(--primary-color); outline-offset: 2px; }
#level-up-wizard-modal .wizard-footer-buttons { gap: 10px; flex-wrap: wrap; }
@media (max-width: 600px) {
    #level-up-wizard-modal :is(.level-up-wizard-header, .level-up-wizard-body, .level-up-wizard-footer) { padding: 16px; }
    #level-up-wizard-modal :is(.ability-scores-grid, .spell-slots-comparison) { grid-template-columns: 1fr; }
}
.detail-sheet .detail-spellcasting { margin-top: 16px; }
.detail-sheet .detail-spellcasting > div { grid-template-columns: 1fr !important; }
.detail-sheet .detail-description { width: 100%; margin-top: 16px; overflow-wrap: anywhere; }
/* NPC sheets share the player sheet's readable stat hierarchy. */
.detail-sheet .npc-ability-inner { display: grid; grid-template-columns: 1fr auto auto; gap: 16px; align-items: center; }
.detail-sheet :is(.npc-ability-name, .npc-level-label, .npc-stat-label, .npc-ac-label) { color: var(--text-light); font-size: 13px; }
.detail-sheet :is(.npc-ability-score, .npc-ac-value, .npc-level-value) { color: var(--text-light); font-size: 16px; font-weight: 600; }
.detail-sheet .npc-ability-modifier { color: var(--primary-color); font-variant-numeric: tabular-nums; }
.detail-sheet .npc-abilities-container { height: auto; }
.detail-sheet .detail-sheet-portrait > div:first-child > div { opacity: 1 !important; color: var(--text-light) !important; }

/* Two balanced sheet regions: grouped statistics and artwork/story. */
.detail-sheet .detail-sheet-overview { grid-template-columns: minmax(0, 1.85fr) minmax(260px, 1fr) !important; max-width: 1600px !important; }
.detail-sheet .detail-sheet-stats { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 0; padding: 16px 0; background: var(--surface-panel); border: 1px solid var(--border-color); border-radius: 10px; box-shadow: 0 4px 18px var(--shadow-primary-25); align-items: start; }
.detail-sheet-stats > div { min-width: 0; height: auto !important; padding: 0 16px; }
.detail-sheet-stats > div + div { border-left: 1px solid var(--border-color); }
.detail-sheet .detail-sheet-stats :is(.detail-sheet-panel, .npc-combat-panel, .npc-abilities-container) { padding: 0 !important; background: transparent !important; border: 0 !important; border-radius: 0 !important; box-shadow: none !important; }
.detail-sheet .detail-sheet-stats [style*="border-left: 2px"],
.detail-sheet .detail-sheet-stats > div > div > div[style*="background"]:not(.detail-sheet-panel) { background: transparent !important; border-left: 0 !important; border-bottom: 1px solid var(--border-color); border-radius: 0 !important; padding: 9px 0 !important; }
.detail-sheet .detail-sheet-stats .detail-spellcasting { padding-top: 16px !important; border-top: 1px solid var(--border-color) !important; }
.detail-sheet .detail-sheet-portrait { padding: 16px; background: var(--surface-panel); border: 1px solid var(--border-color); border-radius: 10px; box-shadow: 0 4px 18px var(--shadow-primary-25); }
.detail-sheet .detail-sheet-portrait .detail-description { padding: 16px 0 0 !important; margin-bottom: 0 !important; border: 0 !important; border-top: 1px solid var(--border-color) !important; border-radius: 0 !important; box-shadow: none; }
.detail-sheet .detail-tab-container { display: flex; gap: 4px; padding: 5px; background: var(--surface-panel); border: 1px solid var(--border-color); border-radius: 8px; }
.detail-sheet .detail-tab-container > .detail-tab-btn { margin: 0 !important; padding: 10px 16px !important; border: 1px solid transparent !important; border-radius: 5px !important; background: transparent !important; color: var(--text-light) !important; box-shadow: none !important; font-weight: 500 !important; }
.detail-sheet .detail-tab-container > .detail-tab-btn.active { background: var(--accent-primary-20) !important; border-color: var(--primary-color) !important; color: var(--text-light) !important; }
.detail-sheet .detail-tab-container > .detail-tab-btn:hover { background: var(--accent-primary-20) !important; }
@media (max-width: 1000px) {
    .detail-sheet .detail-sheet-overview { grid-template-columns: minmax(0, 1fr) !important; }
    .detail-sheet .detail-sheet-portrait { display: grid !important; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 20px; align-items: start !important; }
}
@media (max-width: 600px) {
    .detail-sheet .detail-sheet-stats { grid-template-columns: minmax(0, 1fr); }
    .detail-sheet-stats > div + div { border-left: 0; border-top: 1px solid var(--border-color); padding-top: 16px; margin-top: 16px; }
    .detail-sheet .detail-sheet-portrait { display: flex !important; }
}

/* Equal stat columns above a full-width skills and passive-scores row. */
.detail-sheet .detail-sheet-stats { align-items: stretch; }
.detail-sheet-stats > div { width: 100%; box-sizing: border-box; }
.detail-sheet .detail-sheet-skills { grid-column: 1 / -1; padding: 16px; margin-top: 16px; border-top: 1px solid var(--border-color); }
.detail-sheet .detail-inline-skills { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; }
.detail-sheet .detail-inline-skills > div { margin: 0 !important; padding: 0 !important; background: transparent !important; border: 0 !important; }
.detail-sheet .detail-inline-skills strong { color: var(--text-light) !important; font-size: 13px !important; }
.detail-sheet .detail-inline-skills [style*="background"] { background: transparent !important; border-color: var(--border-color) !important; }
.detail-sheet .detail-inline-skills [style*="font-size: 0."] { font-size: 12px !important; }
.detail-sheet .detail-inline-skills > div:first-child:last-child { grid-column: 1 / -1; }
@media (max-width: 700px) { .detail-sheet .detail-inline-skills { grid-template-columns: 1fr; } }
.detail-sheet .detail-level-badge { padding: 5px 12px; border: 1px solid var(--border-color); border-radius: 6px; background: var(--accent-primary-20); color: var(--text-light); font-size: 14px; white-space: nowrap; }
.detail-sheet .detail-identity { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 20px; width: 100%; margin: 16px 0 0; padding: 16px 0 0; border-top: 1px solid var(--border-color); }
.detail-sheet .detail-identity dt { font-size: 12px; color: var(--text-light); opacity: .75; }
.detail-sheet .detail-identity dd { margin: 3px 0 0; font-size: 15px; color: var(--text-light); overflow-wrap: anywhere; }
@media (max-width: 1000px) { .detail-sheet .detail-sheet-portrait { display: flex !important; } }
/* Shared text and number alignment across both sheet renderers. */
.detail-sheet .sheet-section-title { margin: 0 0 8px; min-height: 24px; font-size: 13px; line-height: 24px; font-weight: 600; color: var(--text-light); }
.detail-sheet .sheet-ability-values, .detail-sheet .npc-ability-inner { display: grid !important; grid-template-columns: minmax(0, 1fr) 3ch 4ch; gap: 12px !important; width: 100%; align-items: center; }
.detail-sheet .sheet-ability-values span, .detail-sheet .npc-ability-inner span { min-width: 0 !important; font-size: 14px !important; line-height: 24px; font-variant-numeric: tabular-nums; }
.detail-sheet .sheet-ability-values span:first-child { color: var(--text-light) !important; }
.detail-sheet .sheet-ability-values span:not(:first-child), .detail-sheet .npc-ability-inner span:not(:first-child) { text-align: right !important; }
.detail-sheet .detail-save-row { min-height: 44px; padding: 9px 0; }
.detail-sheet .detail-save-label { line-height: 24px; }
.detail-sheet .save-proficiency-badge { display: inline-block; margin: 0 0 0 6px; font-size: 11px; line-height: 18px; vertical-align: middle; }
.detail-sheet .detail-save-value { min-width: 4ch; text-align: right; font-variant-numeric: tabular-nums; }
.detail-sheet .detail-spellcasting > div > div { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; }
.detail-sheet .detail-inline-skills > div:first-child > div { display: flex !important; flex-direction: column; gap: 0 !important; }
.detail-sheet .detail-inline-skills > div:first-child > div > div { display: flex; justify-content: space-between; align-items: baseline; gap: 12px; padding: 9px 0 !important; border: 0 !important; border-bottom: 1px solid var(--border-color) !important; border-radius: 0 !important; }
.detail-sheet .detail-inline-skills > div:first-child > div > div > div { margin: 0 !important; color: var(--text-light) !important; text-align: right; font-variant-numeric: tabular-nums; }
.detail-sheet .detail-identity > div { display: grid; grid-template-columns: 5em minmax(0, 1fr); align-items: baseline; gap: 8px; }
.detail-sheet .detail-identity dd { margin: 0; }
.detail-sheet .sheet-combat-metric { padding: 10px 0; border-bottom: 1px solid var(--border-color); }
.detail-sheet .sheet-metric-line { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; min-height: 26px; font-size: 14px; }
.detail-sheet .sheet-metric-line strong { font-size: 16px !important; font-variant-numeric: tabular-nums; color: var(--text-light) !important; }
.detail-sheet .sheet-metric-controls { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px; margin-top: 8px; }
.detail-sheet .sheet-metric-controls button { width: auto !important; padding: 5px 8px !important; min-height: 30px; font-size: 12px !important; }
.detail-sheet .sheet-hp-track { height: 5px; border-radius: 3px; overflow: hidden; background: var(--surface-base); margin-top: 6px; }
.detail-sheet .detail-sheet-panel > div:has(> .long-rest-btn) { flex-wrap: wrap; }
.detail-sheet .detail-sheet-panel > div:has(.long-rest-btn) { flex-wrap: wrap; gap: 8px; }
.detail-sheet :is(.long-rest-btn,.short-rest-btn) { padding: 5px 7px !important; min-height: 30px; font-size: 12px !important; }
.detail-sheet .sheet-metric-controls { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.detail-sheet .sheet-metric-controls > button:only-child { grid-column: 2; }
.detail-sheet .detail-sheet-stats div:has(> div > .sheet-ability-values) { gap: 0 !important; }
.detail-sheet .detail-sheet-stats div:has(> .sheet-ability-values) { min-height: 44px; box-sizing: border-box; }
/* Actions use the same content surface and typography as other sheet tabs. */
.detail-sheet .detail-tab-content .creature-action-row { background: var(--surface-panel); border: 1px solid var(--border-color) !important; border-radius: 8px !important; padding: 16px !important; }
.detail-sheet .creature-action-row > div:first-child { flex-wrap: wrap; align-items: flex-start !important; }
.detail-sheet .creature-action-row strong { color: var(--text-light) !important; font-size: 14px; }
.detail-sheet .creature-action-row > div:first-child > div:first-child > span { display: block; margin-top: 4px; font-size: 13px !important; }

/* Creature-action picker shares the sheet's theme and spacing. */
#creature-action-modal .modal-content { width: min(640px, 92vw); max-width: 640px; padding: 24px; background: var(--surface-panel); color: var(--text-light); border: 1px solid var(--border-color); border-radius: 12px; box-shadow: 0 0 28px var(--shadow-primary-25); }
#creature-action-modal h2 { margin: 0 0 20px; padding-bottom: 16px; border-bottom: 1px solid var(--border-color); color: var(--text-light); font: 500 24px Georgia, serif; }
#creature-action-modal .pick-creature-action-btn { padding: 14px 16px !important; margin-bottom: 8px !important; border: 1px solid var(--border-color) !important; border-radius: 8px !important; background: var(--surface-base) !important; color: var(--text-light) !important; line-height: 1.5; }
#creature-action-modal .pick-creature-action-btn strong { display: block; font-size: 15px; }
#creature-action-modal .pick-creature-action-btn span { display: block; margin-top: 4px; font-size: 13px !important; }
#creature-action-modal .pick-creature-action-btn:hover { border-color: var(--primary-color) !important; box-shadow: 0 0 10px var(--shadow-primary-25); }
#creature-action-modal .modal-actions { margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--border-color); display: flex; justify-content: flex-end; }
#creature-action-modal .modal-actions button { min-height: 36px; padding: 8px 16px; border: 1px solid var(--border-color); border-radius: 6px; background: var(--surface-base); color: var(--text-light); font-size: 14px; }
#creature-action-modal button:focus-visible { outline: 2px solid var(--primary-color); outline-offset: 2px; }

/* Shared styling for add menus on character and NPC sheets only. */
.sheet-add-modal .modal-content { width: min(880px, 94vw); max-width: 880px; max-height: 90vh; overflow-y: auto; padding: 24px; background: var(--surface-panel) !important; color: var(--text-light); border: 1px solid var(--border-color) !important; border-radius: 12px; box-shadow: 0 0 24px var(--shadow-primary-25); font-size: 14px; line-height: 1.6; }
.sheet-add-modal :is(.modal-header, .modal-content > div:first-child:has(h2)) { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 12px; margin-bottom: 20px; padding: 0 0 16px; border-bottom: 1px solid var(--border-color); background: transparent; }
.sheet-add-modal h2 { margin: 0; color: var(--text-light) !important; font: 500 24px Georgia, serif; }
.sheet-add-modal :is(input:not([type=checkbox]):not([type=radio]), select, textarea) { padding: 9px 12px; min-height: 38px; border: 1px solid var(--border-color) !important; border-radius: 6px; background: var(--surface-base) !important; color: var(--text-light) !important; font: inherit; box-sizing: border-box; max-width: 100%; }
.sheet-add-modal div:has(> input[type=text]) { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; margin-bottom: 16px; }
.sheet-add-modal input[type=text] { flex: 1 1 220px; }
.sheet-add-modal :is(button, .btn) { min-height: 36px; padding: 8px 12px; border: 1px solid var(--border-color); border-radius: 6px; background: var(--surface-base); color: var(--text-light); font-size: 13px; }
.sheet-add-modal button:hover, .sheet-add-modal .inventory-db-card:hover { border-color: var(--primary-color) !important; box-shadow: 0 0 10px var(--shadow-primary-25); }
.sheet-add-modal :is(button, input, select, textarea):focus-visible { outline: 2px solid var(--primary-color); outline-offset: 2px; }
.sheet-add-modal :is(#inventory-db-grid, #spell-db-grid, #feature-db-grid, #background-db-grid) { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr)); gap: 12px; max-height: 55vh; overflow-y: auto; padding: 2px; }
.sheet-add-modal :is(.inventory-db-card, #background-db-grid > div) { background: var(--surface-base) !important; border: 1px solid var(--border-color) !important; border-radius: 8px !important; padding: 16px !important; box-shadow: none; margin: 0 !important; }
.sheet-add-modal .inventory-db-header { background: transparent; padding: 0 0 10px; border-bottom: 1px solid var(--border-color); }
.sheet-add-modal .inventory-db-name { color: var(--text-light); font-size: 15px; font-weight: 600; }
.sheet-add-modal .inventory-db-tag { font-size: 12px; }
.sheet-add-modal .inventory-db-body { padding: 12px 0 0; font-size: 13px; color: var(--text-light); line-height: 1.6; }
.sheet-add-modal .modal-content > div:last-child:not(:first-child) { margin-top: 16px; font-size: 13px; }
.detail-sheet .detail-tab-content { padding: 16px 0; font-size: 14px; }
.detail-sheet .detail-tab-content :is(input, select, textarea) { background: var(--surface-base) !important; color: var(--text-light) !important; border: 1px solid var(--border-color) !important; border-radius: 6px; padding: 8px 10px !important; font-size: 13px !important; min-height: 36px; }
.detail-sheet .detail-tab-content [style*="background: rgba(27, 42, 106"] { border: 1px solid var(--border-color) !important; border-radius: 8px !important; padding: 14px !important; box-shadow: none; }
.detail-sheet .detail-tab-content [style*="display: flex"][style*="space-between"] { gap: 12px; flex-wrap: wrap; }
.detail-sheet .detail-tab-content :is(h3, h4, strong) { color: var(--text-light); }
@media (max-width: 600px) { .sheet-add-modal .modal-content { padding: 16px; } }
.sheet-add-modal #background-db-grid [style*="font-size: 0."] { font-size: 13px !important; }
.sheet-add-modal #background-db-grid strong { color: var(--text-light) !important; }
.sheet-add-modal #background-db-grid [style*="font-weight: 600"] { color: var(--text-light) !important; font-size: 15px !important; }
.sheet-add-modal #background-db-grid > div:hover { border-color: var(--primary-color) !important; box-shadow: 0 0 10px var(--shadow-primary-25); }
