/* Popular POEM Custom Styles */

/* Reduced motion — collapse every transition and animation to ~instant.
   Fires on either signal: OS-level Reduce Motion (prefers-reduced-motion
   media query) OR the user's explicit toggle on the preferences page.
   The 0.01ms duration (vs. 0) ensures transitionend events still fire so
   any JS listening for them doesn't break. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        transition-duration: 0.01ms !important;
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        scroll-behavior: auto !important;
    }
}
html[data-reduced-motion="true"] *,
html[data-reduced-motion="true"] *::before,
html[data-reduced-motion="true"] *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    scroll-behavior: auto !important;
}

/* Root font-size scale — drives every rem-based size site-wide.
   Use % (not rem) on :root to avoid circular reference. */
html[data-font-size="small"]   { font-size: 87.5%;  }   /* ~14px */
html[data-font-size="medium"]  { font-size: 100%;   }   /* ~16px (default) */
html[data-font-size="large"]   { font-size: 112.5%; }   /* ~18px */
html[data-font-size="x-large"] { font-size: 125%;   }   /* ~20px */

/* Color scheme — Default theme.
   Adding a new theme = adding a [data-theme="<name>"] block that overrides any subset
   of these tokens. Status colors (warning/danger/success) and the country-distribution
   palette (lives in main.js) are intentionally kept constant across themes for clarity.

   ⚠  PALETTE CHANGE? BUMP SPECTRUM_CACHE_VERSION
   The preferences page caches each theme's computed spectrum in sessionStorage.
   When you change any --pp-* color token here, bump SPECTRUM_CACHE_VERSION in
   popular_poem/templates/account/preferences.html (search the file for that
   constant — it's a short string like 'v3'). Otherwise tabs that already
   loaded the page will keep painting the old spectrum until they close. */
:root,
[data-theme="default"] {
    /* Surfaces */
    --pp-bg:           #f0f2f5;
    --pp-surface:      #ffffff;
    --pp-surface-alt:  #f8f9fa;

    /* Text */
    --pp-text:         #212529;
    --pp-heading:      #212529;
    --pp-text-muted:   #6c757d;
    --pp-text-dim:     #495057;

    /* Borders */
    --pp-border:        #dee2e6;
    --pp-border-strong: #adb5bd;

    /* Brand / interactive */
    --pp-accent:       #0d6efd;
    --pp-accent-hover: #0b5ed7;
    --pp-on-accent:    #ffffff;  /* foreground on top of --pp-accent (buttons, etc.) */
    --pp-link:         #0d6efd;
    --pp-focus-ring:   #0d6efd;
    --pp-navbar:       #343a40;
    --pp-card-shadow:  rgba(0, 0, 0, 0.075);

    /* Status (constant across themes by design) */
    --pp-warning: #ffc107;
    --pp-danger:  #dc3545;
    --pp-success: #198754;

    /* Streak badge — defaults to the theme's accent pair so each theme self-skins.
       HC variants override below (signal conventions take precedence). */
    --pp-streak-bg: var(--pp-accent);
    --pp-streak-fg: var(--pp-on-accent, #ffffff);

    /* Globe */
    --pp-globe-space:           #f0f2f5;
    --pp-globe-ocean:           #b8d8e8;
    --pp-globe-grid:            #4a90d9;
    --pp-globe-country:         #ffffff;
    --pp-globe-country-hover:   #4a90d9;
    --pp-globe-border-active:   #6ea8fe;   /* light-theme convention: selection (highlight) darker than outline */
    --pp-globe-border-inactive: #666666;
    --pp-globe-border-ocean:    #808080;
    --pp-globe-highlight:       #0d6efd;
    --pp-globe-grid-opacity:    0.3;
    --pp-globe-crosshair:       rgba(33, 37, 41, 0.45);   /* dark grey on light globes; dark themes override */

    /* Chart "Other" bucket (8 categorical colors stay fixed) */
    --pp-pie-other: #bab0ab;

    /* Bind Bootstrap's body-bg to our surface token so form-controls,
       dropdowns, and modals follow the theme. CSS vars resolve lazily,
       so each theme's --pp-surface override flows through automatically. */
    --bs-body-bg: var(--pp-surface);
    --bs-heading-color: var(--pp-heading);
}

/* Dark theme — near-black surfaces, lighter blue accents. */
[data-theme="dark"] {
    --pp-bg:           #1a1d20;
    --pp-surface:      #2b2f33;
    --pp-surface-alt:  #25282c;
    --pp-text:         #e9ecef;
    --pp-heading:      #ffffff;
    --pp-text-muted:   #adb5bd;
    --pp-text-dim:     #ced4da;
    --pp-border:        #495057;
    --pp-border-strong: #6c757d;
    --pp-accent:       #6ea8fe;
    --pp-accent-hover: #8bb9ff;
    --pp-on-accent:    #1a1d20;  /* dark on light-blue accent */
    --pp-link:         #6ea8fe;
    --pp-focus-ring:   #6ea8fe;
    --pp-navbar:       #0f1113;
    --pp-card-shadow:  rgba(0, 0, 0, 0.3);
    --pp-globe-space:           #1a1d20;
    --pp-globe-ocean:           #1a3a5a;
    --pp-globe-grid:            #6ea8fe;
    --pp-globe-country:         #6c757d;
    --pp-globe-country-hover:   #6ea8fe;
    --pp-globe-border-active:   #6ea8fe;   /* dark-theme convention: selection (highlight) brighter than outline */
    --pp-globe-border-inactive: #adb5bd;
    --pp-globe-border-ocean:    #495057;
    --pp-globe-highlight:       #ffffff;
    --pp-globe-crosshair:       rgba(255, 255, 255, 0.55);
    --pp-pie-other: #6c757d;
}

/* High Contrast theme — maximum legibility, accessibility-first. */
[data-theme="high-contrast"] {
    --pp-bg:           #ffffff;
    --pp-surface:      #ffffff;
    --pp-surface-alt:  #ffffff;
    --pp-text:         #000000;
    --pp-heading:      #000000;
    --pp-text-muted:   #000000;
    --pp-text-dim:     #000000;
    --pp-border:        #000000;
    --pp-border-strong: #000000;
    --pp-accent:       #0000aa;
    --pp-accent-hover: #000077;
    --pp-link:         #0000aa;
    --pp-focus-ring:   #ff0000;
    --pp-navbar:       #000000;
    --pp-card-shadow:  rgba(0, 0, 0, 0.5);
    --pp-globe-space:           #ffffff;
    --pp-globe-ocean:           #e0e0e0;
    --pp-globe-grid:            #000000;
    --pp-globe-country:         #ffffff;
    --pp-globe-country-hover:   #ffff00;
    /* Light-theme selection convention: outline starts as a deep orange that
       reads on white land (~3.9:1), selection goes DARKER to HC blue — same
       blue as accent/link/search-button so selection ties into the existing
       HC interaction vocabulary. Has-poems vs no-poems separates by color
       (orange vs black) so the distinction no longer depends on opacity alone. */
    --pp-globe-border-active:   #cc6600;
    --pp-globe-border-inactive: #000000;
    --pp-globe-border-ocean:    #000000;
    --pp-globe-highlight:       #0000aa;
    /* Hide the lat/lon grid in HC — decorative clutter that interferes
       with country recognition for low-vision users. */
    --pp-globe-grid-opacity:    0;
    --pp-pie-other: #000000;
    --pp-streak-bg: #ffffff;   /* white pill on the black navbar — mirrors the search button's outline treatment */
    --pp-streak-fg: #0000aa;
}

/* High Contrast (Dark) theme — pure black/white with yellow accents.
   Mirrors HC Light for users with photophobia / glare sensitivity.
   Yellow accent follows the Windows HC Black convention (highest-luminance
   sRGB color, maximum attention draw). Cyan for links per same tradition. */
[data-theme="high-contrast-dark"] {
    --pp-bg:           #000000;
    --pp-surface:      #000000;
    --pp-surface-alt:  #000000;
    --pp-text:         #ffffff;
    --pp-heading:      #ffffff;
    --pp-text-muted:   #ffffff;
    --pp-text-dim:     #ffffff;
    --pp-border:        #ffffff;
    --pp-border-strong: #ffffff;
    --pp-accent:       #ffff00;
    --pp-accent-hover: #ffffaa;
    --pp-on-accent:    #000000;  /* black text on yellow buttons — WCAG ~19:1 */
    --pp-link:         #00ffff;
    --pp-focus-ring:   #ffff00;
    --pp-navbar:       #000000;
    --pp-card-shadow:  rgba(255, 255, 255, 0.4);
    --pp-globe-space:           #000000;
    --pp-globe-ocean:           #303030;
    --pp-globe-grid:            #ffffff;
    --pp-globe-country:         #000000;
    --pp-globe-country-hover:   #ffff00;
    --pp-globe-border-active:   #ffffff;
    --pp-globe-border-inactive: #ffffff;
    --pp-globe-border-ocean:    #ffffff;
    --pp-globe-highlight:       #ffff00;
    --pp-globe-grid-opacity:    0;
    --pp-globe-crosshair:       #ffff00;   /* HC yellow — max attention */
    --pp-pie-other: #ffffff;
    --pp-streak-bg: #ffff00;   /* HC yellow on black — standard HC signal pair */
    --pp-streak-fg: #000000;
}

/* Color Blind Safe theme — Okabe-Ito-derived palette (Nature Methods 2011).
   Distinguishable for protanopia / deuteranopia / tritanopia without going
   to High-Contrast extremes. Globe and interactive accents use Okabe-Ito
   blue / vermillion / orange — pairs chosen so no two adjacent UI states
   collapse into the same hue for any common CB type.
   Status colors (warning/danger/success) stay constant by convention and
   are paired with text/icons elsewhere so CB users still get the signal. */
[data-theme="color-blind"] {
    --pp-bg:           #f5f3ee;
    --pp-surface:      #ffffff;
    --pp-surface-alt:  #ebe9e3;
    --pp-text:         #1d1d1d;
    --pp-heading:      #000000;
    --pp-text-muted:   #555555;
    --pp-text-dim:     #333333;
    --pp-border:        #b5b1a8;
    --pp-border-strong: #6f6c64;
    --pp-accent:       #0072B2;   /* Okabe-Ito blue */
    --pp-accent-hover: #005a8e;
    --pp-on-accent:    #ffffff;
    --pp-link:         #0072B2;
    --pp-focus-ring:   #D55E00;   /* vermillion — pops on both blue and orange */
    --pp-navbar:       #1d1d1d;
    --pp-card-shadow:  rgba(0, 0, 0, 0.12);
    --pp-globe-space:           #f5f3ee;
    --pp-globe-ocean:           #cfe4ee;
    --pp-globe-grid:            #0072B2;
    --pp-globe-country:         #ffffff;
    --pp-globe-country-hover:   #E69F00;   /* Okabe-Ito orange */
    /* Light-theme selection convention: outline starts as Okabe-Ito vermillion
       (3.9:1 on white land — distinct from the blue grid and accent), selection
       goes darker to black for maximum prominence. Grid stays blue so the
       hue trio (grid-blue, outline-vermillion, selection-black) covers CB-safe
       perceptual distinctions while keeping the selection clearly emphasized. */
    --pp-globe-border-active:   #D55E00;
    --pp-globe-border-inactive: #6f6c64;
    --pp-globe-border-ocean:    #6f6c64;
    --pp-globe-highlight:       #000000;
    --pp-globe-grid-opacity:    0.3;
    --pp-pie-other: #b5b1a8;
}

/* Color Blind Safe (Dark) — same CB-safe design goals as the Light variant
   but on dark surfaces. Uses lifted Okabe-Ito / Paul-Tol-bright hues that
   keep contrast against a near-black background. Sky-blue accent + orange
   country hover + vermillion highlight form a CB-safe triple distinct for
   all major CB types. */
[data-theme="color-blind-dark"] {
    --pp-bg:           #1a1d20;
    --pp-surface:      #2b2f33;
    --pp-surface-alt:  #25282c;
    --pp-text:         #e9ecef;
    --pp-heading:      #ffffff;
    --pp-text-muted:   #adb5bd;
    --pp-text-dim:     #ced4da;
    --pp-border:        #495057;
    --pp-border-strong: #6c757d;
    --pp-accent:       #56B4E9;   /* Okabe-Ito sky blue — bright on dark */
    --pp-accent-hover: #87cdf0;
    --pp-on-accent:    #0a1620;   /* dark text on light-blue accent */
    --pp-link:         #56B4E9;
    --pp-focus-ring:   #F0E442;   /* Okabe-Ito yellow — pops on dark + on the blue accent */
    --pp-navbar:       #0f1113;
    --pp-card-shadow:  rgba(0, 0, 0, 0.4);
    --pp-globe-space:           #1a1d20;
    --pp-globe-ocean:           #1a3a5a;
    --pp-globe-grid:            #56B4E9;
    --pp-globe-country:         #6c757d;
    --pp-globe-country-hover:   #E69F00;   /* Okabe-Ito orange — distinct from sky-blue accent */
    --pp-globe-border-active:   #E69F00;   /* Okabe-Ito orange — better contrast against grey land than vermillion; sister to selection-white in palette */
    --pp-globe-border-inactive: #adb5bd;
    --pp-globe-border-ocean:    #495057;
    --pp-globe-highlight:       #ffffff;
    --pp-globe-grid-opacity:    0.3;
    --pp-globe-crosshair:       rgba(240, 228, 66, 0.7);   /* yellow — matches focus ring */
    --pp-pie-other: #6c757d;
}

/* Twilight theme — soft purple-blue, dimmer and warmer than Dark. */
[data-theme="twilight"] {
    --pp-bg:           #2a2438;
    --pp-surface:      #3d3450;
    --pp-surface-alt:  #322a44;
    --pp-text:         #e8dff0;
    --pp-heading:      #f8f0ff;
    --pp-text-muted:   #b0a4c0;
    --pp-text-dim:     #c8bcd8;
    --pp-border:        #5a4f6e;
    --pp-border-strong: #7d6e98;
    --pp-accent:       #b48cd8;
    --pp-accent-hover: #cdaae8;
    --pp-on-accent:    #1a1428;  /* dark on lavender accent */
    --pp-link:         #b48cd8;
    --pp-focus-ring:   #b48cd8;
    --pp-navbar:       #1a1428;
    --pp-card-shadow:  rgba(0, 0, 0, 0.4);
    --pp-globe-space:           #2a2438;
    --pp-globe-ocean:           #2d3a5a;
    --pp-globe-grid:            #b48cd8;
    --pp-globe-country:         #4d4068;
    --pp-globe-country-hover:   #b48cd8;
    --pp-globe-border-active:   #ffaa8c;   /* dark-theme convention: selection brighter than outline */
    --pp-globe-border-inactive: #b0a4c0;
    --pp-globe-border-ocean:    #5a4f6e;
    --pp-globe-highlight:       #f8f0ff;
    --pp-globe-crosshair:       rgba(248, 240, 255, 0.6);
    --pp-pie-other: #7d6e98;
}

/* Cyberpunk theme — deep purple-black surfaces, neon cyan/magenta accents. */
[data-theme="cyberpunk"] {
    --pp-bg:           #0a0a18;
    --pp-surface:      #14142a;
    --pp-surface-alt:  #0f0f20;
    --pp-text:         #c8e8f0;
    --pp-heading:      #ff44dd;
    --pp-text-muted:   #7090a8;
    --pp-text-dim:     #98b8d0;
    --pp-border:        #303058;
    --pp-border-strong: #505080;
    --pp-accent:       #00f5ff;
    --pp-accent-hover: #5cffff;
    --pp-on-accent:    #000000;  /* black text on cyan buttons */
    --pp-link:         #ff44dd;
    --pp-focus-ring:   #ff44dd;  /* hot pink matches heading/link — coherent across focus indicators */
    --pp-navbar:       #000010;
    --pp-card-shadow:  rgba(0, 245, 255, 0.25);
    --pp-globe-space:           #0a0a18;
    --pp-globe-ocean:           #1a0838;
    --pp-globe-grid:            #ff00ff;
    --pp-globe-country:         #2a1a4a;
    --pp-globe-country-hover:   #ff44dd;
    --pp-globe-border-active:   #00f5ff;
    --pp-globe-border-inactive: #505080;
    --pp-globe-border-ocean:    #303058;
    --pp-globe-highlight:       #ffff00;
    --pp-globe-crosshair:       rgba(0, 245, 255, 0.7);   /* neon cyan crosshair */
    --pp-pie-other: #505080;
}

/* Solarized Dark — Ethan Schoonover's classic palette, dark variant. */
[data-theme="solarized-dark"] {
    --pp-bg:           #002b36;
    --pp-surface:      #073642;
    --pp-surface-alt:  #003540;
    --pp-text:         #839496;
    --pp-heading:      #93a1a1;
    --pp-text-muted:   #586e75;
    --pp-text-dim:     #657b83;
    --pp-border:        #205060;
    --pp-border-strong: #586e75;
    --pp-accent:       #268bd2;
    --pp-accent-hover: #4ba0e0;
    --pp-link:         #268bd2;
    --pp-focus-ring:   #268bd2;
    --pp-navbar:       #001a20;
    --pp-card-shadow:  rgba(0, 0, 0, 0.4);
    --pp-globe-space:           #002b36;
    --pp-globe-ocean:           #003540;
    --pp-globe-grid:            #268bd2;
    --pp-globe-country:         #586e75;
    --pp-globe-country-hover:   #268bd2;
    --pp-globe-border-active:   #93a1a1;
    --pp-globe-border-inactive: #586e75;
    --pp-globe-border-ocean:    #205060;
    --pp-globe-highlight:       #fdf6e3;
    --pp-globe-crosshair:       rgba(253, 246, 227, 0.55);
    --pp-pie-other: #586e75;
}

/* Nautical theme — old-map blue with brass accents, weathered chart paper. */
[data-theme="nautical"] {
    --pp-bg:           #e8eef0;
    --pp-surface:      #f4f6f0;
    --pp-surface-alt:  #d8e0e4;
    --pp-text:         #1a2a40;
    --pp-heading:      #0a1830;
    --pp-text-muted:   #5a7088;
    --pp-text-dim:     #3a4e68;
    --pp-border:        #b0c0c8;
    --pp-border-strong: #788998;
    --pp-accent:       #b8860b;
    --pp-accent-hover: #8b6914;
    --pp-link:         #1a2a40;
    --pp-focus-ring:   #b8860b;
    --pp-navbar:       #0a1830;
    --pp-card-shadow:  rgba(10, 24, 48, 0.15);
    --pp-globe-space:           #e8eef0;
    --pp-globe-ocean:           #4878a0;
    --pp-globe-grid:            #1a2a40;
    --pp-globe-country:         #f5e8c8;
    --pp-globe-country-hover:   #b8860b;
    --pp-globe-border-active:   #5a7088;   /* light-theme convention: selection darker than outline */
    --pp-globe-border-inactive: #3a4e68;
    --pp-globe-border-ocean:    #788998;
    --pp-globe-highlight:       #0a1830;
    --pp-globe-grid-opacity:    0.4;
    --pp-pie-other: #788998;
}

/* Topographic theme — earthy contour-map vibe, olive green accent. */
[data-theme="topographic"] {
    --pp-bg:           #f0ebde;
    --pp-surface:      #f6f2e8;
    --pp-surface-alt:  #e4dcc8;
    --pp-text:         #3d3020;
    --pp-heading:      #2a1f10;
    --pp-text-muted:   #8b7855;
    --pp-text-dim:     #5c4a30;
    --pp-border:        #d0c0a0;
    --pp-border-strong: #a08c68;
    --pp-accent:       #6b8e23;
    --pp-accent-hover: #4d6e15;
    --pp-link:         #6b8e23;
    --pp-focus-ring:   #6b8e23;
    --pp-navbar:       #2a1f10;
    --pp-card-shadow:  rgba(61, 48, 32, 0.12);
    --pp-globe-space:           #f0ebde;
    --pp-globe-ocean:           #c4d4b0;
    --pp-globe-grid:            #6b8e23;
    --pp-globe-country:         #e8d8a8;
    --pp-globe-country-hover:   #6b8e23;
    --pp-globe-border-active:   #6b8e23;   /* light-theme convention: selection darker than outline */
    --pp-globe-border-inactive: #8b7855;
    --pp-globe-border-ocean:    #a08c68;
    --pp-globe-highlight:       #2a1f10;
    --pp-globe-grid-opacity:    0.4;
    --pp-pie-other: #a08c68;
}

/* Solarized Light — Ethan Schoonover's classic palette, light variant. */
[data-theme="solarized-light"] {
    --pp-bg:           #fdf6e3;
    --pp-surface:      #fdf6e3;
    --pp-surface-alt:  #eee8d5;
    --pp-text:         #657b83;
    --pp-heading:      #586e75;
    --pp-text-muted:   #93a1a1;
    --pp-text-dim:     #657b83;
    --pp-border:        #d8d2bf;
    --pp-border-strong: #93a1a1;
    --pp-accent:       #268bd2;
    --pp-accent-hover: #1f6ea0;
    --pp-link:         #268bd2;
    --pp-focus-ring:   #268bd2;
    --pp-navbar:       #073642;
    --pp-card-shadow:  rgba(0, 43, 54, 0.1);
    --pp-globe-space:           #fdf6e3;
    --pp-globe-ocean:           #93a1a1;
    --pp-globe-grid:            #268bd2;
    --pp-globe-country:         #eee8d5;
    --pp-globe-country-hover:   #268bd2;
    --pp-globe-border-active:   #586e75;   /* light-theme convention: selection darker than outline */
    --pp-globe-border-inactive: #657b83;
    --pp-globe-border-ocean:    #93a1a1;
    --pp-globe-highlight:       #002b36;   /* base03 — Solarized's darkest base, maximum contrast vs base01 outline */
    --pp-pie-other: #93a1a1;
}

/* Pastel theme — low-saturation everywhere, gentle on the eyes. */
[data-theme="pastel"] {
    --pp-bg:           #f5f0fa;
    --pp-surface:      #ffffff;
    --pp-surface-alt:  #ece4f5;
    --pp-text:         #4a4055;
    --pp-heading:      #2a2035;
    --pp-text-muted:   #888098;
    --pp-text-dim:     #6a6078;
    --pp-border:        #d8cce5;
    --pp-border-strong: #b0a4bf;
    --pp-accent:       #a890d0;
    --pp-accent-hover: #8870b0;
    --pp-on-accent:    #2a2035;  /* dark on soft-purple accent */
    --pp-link:         #a890d0;
    --pp-focus-ring:   #a890d0;
    --pp-navbar:       #6e5e88;
    --pp-card-shadow:  rgba(74, 64, 85, 0.1);
    --pp-globe-space:           #f5f0fa;
    --pp-globe-ocean:           #c0d8f0;
    --pp-globe-grid:            #a890d0;
    --pp-globe-country:         #fff5e0;
    --pp-globe-country-hover:   #f5a8c0;
    --pp-globe-border-active:   #8870b0;   /* light-theme convention: selection darker than outline */
    --pp-globe-border-inactive: #888098;
    --pp-globe-border-ocean:    #b0a4bf;
    --pp-globe-highlight:       #4a4055;
    --pp-pie-other: #b0a4bf;
}

/* Forge theme — blacksmith dark. Coal black, ember orange, iron grey.
   Warmth in the dark with more energy than Library. */
[data-theme="forge"] {
    --pp-bg:           #0c0a08;
    --pp-surface:      #1f1c18;
    --pp-surface-alt:  #18150f;
    --pp-text:         #e0d8c8;
    --pp-heading:      #ff6a1e;
    --pp-text-muted:   #9a8c78;
    --pp-text-dim:     #c0b09a;
    --pp-border:        #3a3530;
    --pp-border-strong: #5a534a;
    --pp-accent:       #ff6a1e;
    --pp-accent-hover: #ff8a3e;
    --pp-on-accent:    #0c0a08;
    --pp-link:         #ffa060;
    --pp-focus-ring:   #ff6a1e;
    --pp-navbar:       #060504;
    --pp-card-shadow:  rgba(0, 0, 0, 0.4);
    --pp-globe-space:           #0c0a08;
    --pp-globe-ocean:           #1a2028;
    --pp-globe-grid:            #c84a1e;
    --pp-globe-country:         #5a4a3c;
    --pp-globe-country-hover:   #ff6a1e;
    --pp-globe-border-active:   #ff8a3e;   /* dark-theme convention: selection brighter than outline */
    --pp-globe-border-inactive: #6a5a48;
    --pp-globe-border-ocean:    #1a1814;
    --pp-globe-highlight:       #e0d8c8;
    --pp-globe-crosshair:       rgba(224, 216, 200, 0.55);
    --pp-pie-other: #4a4540;
}

/* Vintage Terminal theme — green phosphor on CRT charcoal.
   Retro-tech mood — distinct from Cyberpunk's futuristic neon. */
[data-theme="vintage-terminal"] {
    --pp-bg:           #0a0d08;
    --pp-surface:      #15180f;
    --pp-surface-alt:  #10130b;
    --pp-text:         #4afa70;
    --pp-heading:      #6cff8c;
    --pp-text-muted:   #4a8a5a;
    --pp-text-dim:     #6ab07a;
    --pp-border:        #1f2818;
    --pp-border-strong: #2a3a22;
    --pp-accent:       #4afa70;
    --pp-accent-hover: #6cff8c;
    --pp-on-accent:    #0a0d08;
    --pp-link:         #4afa70;
    --pp-focus-ring:   #4afa70;
    --pp-navbar:       #040603;
    --pp-card-shadow:  rgba(74, 250, 112, 0.2);
    --pp-globe-space:           #0a0d08;
    --pp-globe-ocean:           #0f1810;
    --pp-globe-grid:            #2a7a3a;
    --pp-globe-country:         #2a3a22;
    --pp-globe-country-hover:   #4afa70;
    --pp-globe-border-active:   #6cff8c;
    --pp-globe-border-inactive: #3a5a32;
    --pp-globe-border-ocean:    #0a1408;
    --pp-globe-highlight:       #ffb000;  /* amber phosphor — selection pops against the green borders */
    --pp-globe-crosshair:       rgba(74, 250, 112, 0.7);
    --pp-pie-other: #2a3a22;
}

/* Beach theme — warm sand surfaces against turquoise sea accents, coral
   sunset headings, lifeguard-tower deep blue navbar. */
[data-theme="beach"] {
    --pp-bg:           #f4ead4;
    --pp-surface:      #fdf8ec;
    --pp-surface-alt:  #ede1c4;
    --pp-text:         #3d2f1f;
    --pp-heading:      #d4541e;
    --pp-text-muted:   #8a7560;
    --pp-text-dim:     #5a4a38;
    --pp-border:        #d4c098;
    --pp-border-strong: #a88858;
    --pp-accent:       #2db4a8;
    --pp-accent-hover: #1a9088;
    --pp-on-accent:    #ffffff;
    --pp-link:         #1a8a80;
    --pp-focus-ring:   #2db4a8;
    --pp-navbar:       #2e7898;
    --pp-card-shadow:  rgba(122, 100, 70, 0.18);
    --pp-globe-space:           #f4ead4;  /* matches --pp-bg so the globe blends into the page */
    --pp-globe-ocean:           #58b8c8;
    --pp-globe-grid:            #2a8898;
    --pp-globe-country:         #f4e6c4;
    --pp-globe-country-hover:   #ff8a5a;
    --pp-globe-border-active:   #d4541e;   /* light-theme convention: selection darker than outline */
    --pp-globe-border-inactive: #b89868;
    --pp-globe-border-ocean:    #2a7888;
    --pp-globe-highlight:       #3d2f1f;
    --pp-globe-crosshair:       rgba(61, 47, 31, 0.45);
    --pp-pie-other: #b89868;
}

/* Prevent horizontal overflow on mobile. `clip` (not `hidden`) avoids
   making <html> a scroll container, which would break sticky + anchor nav. */
html, body {
    overflow-x: clip;
}

/* Body layout for sticky footer */
body {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    background-color: var(--pp-bg);
}

main {
    flex: 1;
}

/* Hero section */
.hero {
    background: var(--pp-bg);
    color: var(--pp-text);
    padding: 4rem 0;
    margin-bottom: 2rem;
}

.hero h1 {
    font-size: 3rem;
    font-weight: bold;
}

/* Hero carousel */
#intro-carousel {
    position: relative;
    margin-bottom: 1rem;
}

#intro-carousel .carousel-inner {
    display: flex;
    align-items: center;
}

#intro-carousel .carousel-item {
    padding: 1rem 3rem;
}

#intro-carousel .carousel-content {
    padding: 1rem;
}

#intro-carousel .carousel-label {
    font-size: 1rem;
    color: var(--pp-text-muted);
    margin-bottom: 0.75rem;
    font-weight: 500;
}

#intro-carousel .carousel-text {
    font-size: 1.25rem;
    line-height: 1.6;
    margin-bottom: 0;
}

#intro-carousel .carousel-poem {
}

#intro-carousel .carousel-control-prev,
#intro-carousel .carousel-control-next {
    width: 10%;
    /* Bootstrap's default is 0.5, which dims the puck+chevron enough that
       on dark themes the light puck washes back into the dark bg. 0.75
       keeps a subtle "not screaming for attention" feel while letting
       the puck actually show — and gives hover a real opacity gap to grow into. */
    opacity: 0.75;
}

#intro-carousel .carousel-control-prev:hover,
#intro-carousel .carousel-control-next:hover {
    opacity: 1;
}

/* Hover: shift the puck to a SOLID theme accent so the mouseover reads as
   a clear state change. Solid (not translucent) is intentional — on dark
   themes the default text-mixed puck and an 80% accent-mixed puck land at
   similar effective lightness, so the hue shift alone wasn't perceptible.
   Solid accent gives both a hue change AND a saturation/brightness jump. */
#intro-carousel .carousel-control-prev:hover .carousel-control-prev-icon,
#intro-carousel .carousel-control-next:hover .carousel-control-next-icon {
    background-color: var(--pp-accent);
}

#intro-carousel .carousel-control-prev-icon,
#intro-carousel .carousel-control-next-icon {
    /* Light themes: a subtle dark tint on the bg — enough to show the disc,
       but light enough that the solid accent on hover reads as a real "pop"
       in both hue AND brightness. Dark themes get bumped to 70% via the
       data-bs-theme="dark" override below since they need more body to read
       against the dark bg. */
    background-color: color-mix(in srgb, var(--pp-text) 30%, transparent);
    border-radius: 50%;
    padding: 1.25rem;
    background-size: 50%;
    transition: background-color 150ms ease;
}

/* Dark themes: Bootstrap 5.3 auto-applies `filter: invert(1) grayscale(100)`
   to carousel-control icons under [data-bs-theme="dark"], which kills our
   accent-color hover by desaturating the puck. Override with filter:none
   so our color tokens render as-authored. Then swap Bootstrap's white-fill
   chevron SVG for a dark-fill version so the arrow contrasts against the
   now-light puck. */
[data-bs-theme="dark"] #intro-carousel .carousel-control-prev-icon,
[data-bs-theme="dark"] #intro-carousel .carousel-control-next-icon {
    filter: none;
    /* Bump default puck opacity 30%→70% on dark themes: the lighter base
       (text color is light on dark themes) needs more body to be visible
       against the dark bg, where light themes only need a subtle tint. */
    background-color: color-mix(in srgb, var(--pp-text) 70%, transparent);
}
[data-bs-theme="dark"] #intro-carousel .carousel-control-prev-icon {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e");
}
[data-bs-theme="dark"] #intro-carousel .carousel-control-next-icon {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
}

/* Language toggle pill */
.lang-toggle {
    display: inline-flex;
    background-color: #e9ecef;
    border-radius: 999px;
    padding: 3px;
    margin-bottom: 0.75rem;
}

.lang-toggle-btn {
    border: none;
    background: none;
    padding: 0.3rem 0.85rem;
    font-size: 0.8rem;
    font-weight: 500;
    color: var(--pp-text-muted);
    border-radius: 999px;
    cursor: pointer;
    transition: background-color 0.25s, color 0.25s, box-shadow 0.25s;
    white-space: nowrap;
}

.lang-toggle-btn.active {
    background-color: var(--pp-surface);
    color: var(--pp-text);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
}

.lang-toggle-btn:hover:not(.active) {
    color: var(--pp-text-dim);
}

/* Language text fade transition */
.lang-text {
    transition: opacity 0.3s ease;
}

.lang-text.d-none {
    display: none !important;
}

.lang-text.fade-out {
    opacity: 0;
}

/* Hero carousel dot indicators */
#intro-carousel .carousel-indicators {
    position: relative;
    margin: 0.75rem 0 0;
}

#intro-carousel .carousel-indicators button {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background-color: var(--pp-border-strong);
    opacity: 0.5;
}

#intro-carousel .carousel-indicators button.active {
    background-color: var(--pp-accent);
    opacity: 1;
}

@media (max-width: 575.98px) {
    main.container {
        padding-left: 4px;
        padding-right: 4px;
    }

    .hero {
        padding: 1rem 0;
        margin-bottom: 0.5rem;
    }

    .hero h1 {
        font-size: 2rem;
    }

    .hero img {
        margin-bottom: 0.5rem !important;
    }

    #intro-carousel {
        margin-bottom: 0.25rem;
    }

    #intro-carousel .carousel-item {
        padding: 0.5rem 0;
    }

    #intro-carousel .carousel-content {
        padding: 0.25rem 0;
    }

    #intro-carousel .carousel-text {
        font-size: 1.05rem;
    }

    #intro-carousel .carousel-label {
        margin-bottom: 0.25rem;
    }

    .lang-toggle-btn {
        font-size: 0.72rem;
        padding: 0.25rem 0.6rem;
    }

    .hero-buttons {
        margin-top: 1rem !important;
    }

    .hero-buttons .btn {
        font-size: 0.9rem;
        padding: 0.4rem 0.9rem;
    }

    footer p.text-muted {
        font-size: 0.55rem;
    }

    footer p.text-muted .mx-2 {
        margin-left: 0.1rem !important;
        margin-right: 0.1rem !important;
    }
}

@media (min-width: 576px) and (max-width: 767.98px) {
    footer p.text-muted {
        font-size: 0.7rem;
    }

    footer p.text-muted .mx-2 {
        margin-left: 0.25rem !important;
        margin-right: 0.25rem !important;
    }
}

/* Cards */
.card {
    background-color: var(--pp-surface);
    transition: box-shadow 0.2s;
}

.card:hover {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

/* Content areas should have white background */
main .container {
    background-color: transparent;
}

/* Fix flexbox shrinking issue with nowrap content */
.poem-lines-column {
    min-width: 0;
    container-type: inline-size; /* Enable container queries */
}

/* Poem lines display */
.poem-lines {
    font-family: 'Hack', monospace;
    /* Use container query units (cqi) to scale based on actual container width
       75 chars in Hack ≈ 45em width, so font ≈ container-width / 50 (with padding buffer).
       Max raised to 1.5rem so the font can fill the column at Bootstrap xl/xxl widths. */
    font-size: clamp(0.45rem, 2cqi, 1.5rem);
    line-height: 1.4;
    padding: 1.5rem;
    background-color: var(--pp-surface-alt);
    border-left: 3px solid var(--pp-accent);
    overflow-x: auto; /* Fallback: contain overflow if font calc is slightly off */
    direction: ltr; /* Poem content is always English/LTR regardless of UI language */
}

.poem-line,
.poem-line:hover,
.poem-line:visited,
.poem-line:active {
    color: inherit;
    text-decoration: none;
}

.poem-line {
    display: block;
    white-space: nowrap;
    cursor: pointer;
    transition: background-color 0.15s ease-in-out;
}

.poem-line.is-touch-active {
    background-color: rgba(13, 110, 253, 0.1);
}

/* Country distribution bar (rendered by JS as inline SVG) */
.country-bar {
    display: none;
    width: 100%;
    height: 4px;
}

.poem-line.is-touch-active + .country-bar {
    display: block;
}

/* Hover styles only apply on fine-pointer devices. On touch, iOS Safari
   leaves :hover stuck on the first-touched element, which would clash
   with the JS-driven .is-touch-active class. */
@media (hover: hover) {
    .poem-line:hover {
        background-color: rgba(13, 110, 253, 0.1);
    }
    .poem-line:hover + .country-bar {
        display: block;
    }
}

/* On touch devices, JS handles drag-to-scrub: take over touch gestures
   inside the poem block so vertical drags scrub lines instead of
   scrolling the page. Edge auto-scroll handles long poems. */
@media (pointer: coarse) {
    .poem-lines {
        touch-action: none;
    }
}

/* Pie chart page */
.poem-line-preview {
    font-family: 'Hack', monospace;
    font-size: 0.95rem;
    background-color: var(--pp-surface-alt);
    padding: 0.75rem 1rem;
    white-space: normal;
    word-break: break-word;
    direction: ltr; /* Poem content is always English/LTR regardless of UI language */
}

.pie-chart {
    display: block;
    margin: 0 auto;
}

.pie-tooltip {
    position: fixed;
    background: rgba(0, 0, 0, 0.75);
    color: #fff;
    padding: 0.3rem 0.65rem;
    border-radius: 4px;
    font-size: 0.85rem;
    pointer-events: none;
    white-space: nowrap;
    z-index: 1000;
}

/* Poem popularity popover */
.poem-popularity-popover {
    --bs-popover-max-width: 250px;
}

.poem-popularity-popover .popover-header {
    font-size: 0.875rem;
    background-color: var(--pp-surface-alt);
}

.poem-popularity-popover .popover-body {
    font-size: 0.875rem;
}

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

.popularity-stats strong {
    font-size: 1.25rem;
    color: var(--pp-accent);
}

/* Poem detail */
.poem-header {
    border-bottom: 2px solid var(--pp-accent);
    padding-bottom: 1rem;
    margin-bottom: 2rem;
}

.poem-position {
    color: var(--pp-text-muted);
}

/* Character counter for message input */
.char-counter {
    font-size: 0.875rem;
    color: var(--pp-text-muted);
}

.char-counter.warning {
    color: var(--pp-warning);
}

.char-counter.danger {
    color: var(--pp-danger);
}

.char-invalid {
    font-size: 0.875rem;
    color: var(--pp-danger);
}

/* Streak badge — colors driven by --pp-streak-bg / --pp-streak-fg tokens
   so themes can re-skin without touching markup. */
.streak-badge {
    display: inline-flex;
    align-items: center;
    padding: 0.5rem 1rem;
    background-color: var(--pp-streak-bg);
    color: var(--pp-streak-fg);
    border-radius: 2rem;
    font-weight: bold;
}
/* Compact variant for the navbar — smaller padding/text so it doesn't
   dominate the bar but stays visible on mobile next to the brand. */
.streak-badge--nav {
    padding: 0.2rem 0.6rem;
    font-size: 0.875rem;
    line-height: 1.2;
}

/* Poem list (compact view) */
.poem-list-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    padding: 0.6rem 1rem;
}

.poem-list-main {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    min-width: 0;
}

.poem-list-main strong {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.poem-list-position {
    font-size: 0.875rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.poem-list-meta {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex-shrink: 0;
}

.poem-list-count {
    font-size: 0.85rem;
    white-space: nowrap;
}

.poem-list-edit {
    font-size: 0.9rem;
    cursor: pointer;
    color: var(--pp-text-muted);
}

.poem-list-edit:hover {
    color: var(--pp-accent);
}

.poem-list-arrow {
    font-size: 1.25rem;
    color: var(--pp-border-strong);
    line-height: 1;
}

@media (max-width: 575.98px) {
    .poem-lines {
        border-left: none;
        padding: 0.75rem 0.25rem;
        font-size: clamp(0.45rem, 2.15cqi, 1.5rem);
    }

    .poem-line-preview {
        white-space: normal;
        word-break: break-word;
        text-align: center;
        font-size: 1.1rem;
        padding: 1rem 0.75rem;
    }

    .poem-list-item {
        flex-wrap: wrap;
    }

    .poem-list-main {
        flex-direction: column;
        gap: 0;
        width: 100%;
    }

    .poem-list-meta {
        width: 100%;
        justify-content: flex-end;
    }
}

/* Search results */
.search-result {
    padding: 1rem;
    border-bottom: 1px solid var(--pp-border);
}

.search-result:last-child {
    border-bottom: none;
}

.search-result:hover {
    background-color: var(--pp-surface-alt);
}

/* Form styling */
textarea.form-control::placeholder {
    color: #c0c5cb;
}

.form-label {
    font-weight: 500;
}

/* Theme-aware range slider. Bootstrap ships .form-range with hardcoded
   greys that vanish on dark themes (Dark, Twilight, etc. where the surface
   is dark and the track stays a too-similar grey). Bind both the thumb
   and the track to theme tokens — accent for the thumb so it pops, and
   border-strong for the track so it always reads against the surface.
   Vendor pseudo-elements must be listed separately; combined selectors
   are silently dropped by the browser if any one element is unrecognized. */
.form-range::-webkit-slider-thumb {
    background-color: var(--pp-accent);
}
.form-range::-moz-range-thumb {
    background-color: var(--pp-accent);
}
.form-range::-webkit-slider-runnable-track {
    background-color: var(--pp-border-strong);
}
.form-range::-moz-range-track {
    background-color: var(--pp-border-strong);
}
.form-range:focus::-webkit-slider-thumb {
    background-color: var(--pp-accent-hover);
    box-shadow: 0 0 0 0.2rem var(--pp-focus-ring);
}
.form-range:focus::-moz-range-thumb {
    background-color: var(--pp-accent-hover);
    box-shadow: 0 0 0 0.2rem var(--pp-focus-ring);
}

/* High-Contrast variants intentionally push --pp-accent and --pp-border-strong
   to opposite extremes (one near-white, one near-black). Binding the thumb
   to accent then collapses it into the extreme track — blue thumb on black
   track in HC Light, yellow thumb on white track in HC Dark. Re-bind the
   thumb to page-bg with a text-color border so it reads as a disc with an
   outline against any track color, and inverts cleanly between HC variants. */
[data-theme="high-contrast"] .form-range::-webkit-slider-thumb,
[data-theme="high-contrast-dark"] .form-range::-webkit-slider-thumb {
    background-color: var(--pp-bg);
    border: 3px solid var(--pp-text);
}
[data-theme="high-contrast"] .form-range::-moz-range-thumb,
[data-theme="high-contrast-dark"] .form-range::-moz-range-thumb {
    background-color: var(--pp-bg);
    border: 3px solid var(--pp-text);
}

/* Button styling - blue buttons */
.btn-primary {
    /* Override Bootstrap's per-state btn vars so text color follows the
       theme's --pp-on-accent token across normal/hover/active. Otherwise
       bright-accent themes (HC Dark yellow, Cyberpunk cyan) inherit
       Bootstrap's default white text and become unreadable. */
    --bs-btn-color:        var(--pp-on-accent);
    --bs-btn-hover-color:  var(--pp-on-accent);
    --bs-btn-active-color: var(--pp-on-accent);
    background-color: var(--pp-accent);
    border-color: var(--pp-accent);
}

.btn-primary:hover {
    background-color: var(--pp-accent-hover);
    border-color: var(--pp-accent-hover);
}

/* High Contrast variants: invert the button — page-bg fill with accent
   border and accent text by default, then fill to accent with bg-colored
   text on hover/focus. Mirrors the Windows HC system-button convention,
   which is less visually shouty than a solid accent rectangle and reads
   as a distinct affordance next to thick-bordered inputs. */
[data-theme="high-contrast"] .btn-primary,
[data-theme="high-contrast-dark"] .btn-primary {
    --bs-btn-color:        var(--pp-accent);
    --bs-btn-hover-color:  var(--pp-bg);
    --bs-btn-active-color: var(--pp-bg);
    background-color: var(--pp-bg);
    border-color: var(--pp-accent);
    border-width: 2px;
}

[data-theme="high-contrast"] .btn-primary:hover,
[data-theme="high-contrast-dark"] .btn-primary:hover {
    background-color: var(--pp-accent);
    border-color: var(--pp-accent);
}

/* Navbar dark grey */
.navbar-dark-grey {
    background-color: var(--pp-navbar) !important;
}

/* Bootstrap's .navbar-dark ships nav-link text at rgba(255,255,255,0.55) —
   the translucency reads as "dim" or "thin" on saturated navbar colors
   (Clown Car red, Forest green, etc.). Force solid white for labels, with
   a slight fade only on hover/focus so the affordance still feels alive. */
.navbar-dark-grey .navbar-nav .nav-link,
.navbar-dark-grey .navbar-brand {
    color: #fff;
}
.navbar-dark-grey .navbar-nav .nav-link:hover,
.navbar-dark-grey .navbar-nav .nav-link:focus {
    color: rgba(255, 255, 255, 0.85);
}

/* Normalize dropdown option height across scripts (Arabic/Devanagari glyphs are taller than Latin) */
footer select.form-select option {
    line-height: 1.5;
    font-size: 0.875rem;
}

/* Alert styling for Django messages */
.alert-debug {
    background-color: #e2e3e5;
    border-color: #d3d6d8;
    color: #41464b;
}

.alert-error {
    background-color: #f8d7da;
    border-color: #f5c2c7;
    color: #842029;
}

/* Autocomplete dropdown */
.autocomplete-results {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    margin-top: 2px;
    background-color: var(--pp-surface);
    border: 1px solid var(--pp-border);
    border-radius: 0.375rem;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    max-height: 300px;
    overflow-y: auto;
    z-index: 1000;
}

.autocomplete-item {
    padding: 0.75rem 1rem;
    cursor: pointer;
}

.autocomplete-item:hover {
    background-color: var(--pp-surface-alt);
}

.autocomplete-item.active {
    background-color: var(--pp-accent);
    color: var(--pp-on-accent);
}

/* Utility class for CSP-compliant hiding (instead of inline style="display: none;") */
.d-none-initial {
    display: none;
}

/* Cookie Consent Banner */
.cookie-consent-banner {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    background-color: var(--pp-navbar);
    color: #ffffff;
    padding: 1rem 0;
    z-index: 9999;
    box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.2);
}

.cookie-consent-banner p {
    margin-bottom: 0;
    font-size: 0.9rem;
}

.cookie-consent-link {
    color: #ffffff;
    text-decoration: underline;
}

.cookie-consent-link:hover {
    color: #e9ecef;
}

/* Cookie consent notice for forms */
.cookie-consent-required {
    background-color: #fff3cd;
    border: 1px solid #ffecb5;
    color: #664d03;  /* Dark amber text; paired with the alert bg, not body color */
    border-radius: 0.375rem;
    padding: 1rem;
    margin-bottom: 1rem;
}

.cookie-consent-required a {
    color: #664d03;
    text-decoration: underline;
    cursor: pointer;
}

/* About page — sidebar nav + scrollspy */
html {
    scroll-behavior: smooth;
}

.about-sidebar {
    position: sticky;
    top: 1rem;
    max-height: calc(100vh - 2rem);
    overflow-y: auto;
    padding-right: 1rem;
}

.about-sidebar .nav-link {
    color: var(--pp-text-dim);
    padding: 0.25rem 0.75rem;
    border-left: 2px solid transparent;
    border-radius: 0;
    font-size: 0.875rem;
    /* Override Bootstrap's 150ms ease-in-out on .nav-link — faster + ease-out
       front-loads the motion so the hover feedback feels immediate. */
    transition: color 80ms ease-out,
                border-color 80ms ease-out;
}

.about-sidebar .nav-link:hover {
    color: var(--pp-link);
    background-color: transparent;
}

.about-sidebar .nav-link.active {
    color: var(--pp-link);
    background-color: transparent;
    border-left-color: var(--pp-accent);
    font-weight: 500;
}

/* About page — mobile TOC */
.about-mobile-toc-link {
    color: var(--pp-text-dim);
    font-size: 0.9rem;
}

.about-mobile-toc-link:hover {
    color: var(--pp-link);
}

.about-nav-top {
    font-weight: 500;
    font-size: 0.9rem !important;
    margin-top: 0.5rem;
}

.about-nav-sub {
    font-size: 0.8rem !important;
}

.about-section {
    padding-bottom: 2rem;
    margin-bottom: 2rem;
    border-bottom: 1px solid var(--pp-border);
}

.about-section:last-child {
    border-bottom: none;
    margin-bottom: 0;
}

.about-section > h1,
.about-section > h2 {
    margin-bottom: 1rem;
}

.about-item {
    background-color: var(--pp-surface);
    border: 1px solid #e9ecef;
    border-radius: 0.5rem;
    padding: 1.25rem 1.5rem;
    margin-bottom: 1rem;
}

.about-subsection {
    font-weight: 600;
    font-size: 1.05rem;
    margin-top: 0;
    margin-bottom: 0.75rem;
    padding-top: 0;
    color: var(--pp-heading);
}

.about-item p:last-child,
.about-item ul:last-child,
.about-item ol:last-child {
    margin-bottom: 0;
}

/* Signup progress steps (1→2→3) */
.signup-progress {
    margin-bottom: 1.5rem;
}
.signup-progress .steps-container {
    display: flex;
    justify-content: space-between;
    align-items: center;
}
.signup-progress .step {
    text-align: center;
    flex: 0 0 auto;
}
.signup-progress .step-number {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: #e9ecef;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-weight: 600;
    font-size: 0.9rem;
}
.signup-progress .step.active .step-number {
    background: var(--pp-accent);
    color: var(--pp-on-accent);
}
.signup-progress .step.completed .step-number {
    background: var(--pp-success);
    color: white;
}
.signup-progress .step-line {
    flex: 1;
    height: 2px;
    background: #e9ecef;
    margin: 0 8px;
}
.signup-progress .step-line.completed {
    background: var(--pp-success);
}
.signup-progress .step-label {
    font-size: 0.85rem;
    margin-top: 4px;
    color: var(--pp-text-muted);
}
.signup-progress .step.active .step-label {
    color: var(--pp-accent);
    font-weight: 500;
}
.signup-progress .step.completed .step-label {
    color: var(--pp-success);
}
@media (max-width: 575.98px) {
    .signup-progress .steps-container {
        max-width: 100%;
        justify-content: center;
        gap: 0;
    }
    .signup-progress .step-number {
        width: 26px;
        height: 26px;
        font-size: 0.75rem;
    }
    .signup-progress .step-label {
        font-size: 0.7rem;
        max-width: 70px;
        word-wrap: break-word;
    }
    .signup-progress .step-line {
        margin: 0 4px;
        flex: 0 1 40px;
    }
}

/* Password visibility toggle */
.password-toggle-wrapper {
    position: relative;
}
.password-toggle-btn {
    position: absolute;
    right: 8px;
    top: 50%;
    transform: translateY(-50%);
    background: none;
    border: none;
    padding: 4px;
    cursor: pointer;
    color: var(--pp-text-muted);
    line-height: 0;
}
.password-toggle-btn:hover {
    color: #343a40;
}
.password-toggle-wrapper input[type="password"],
.password-toggle-wrapper input[type="text"] {
    padding-right: 40px;
}

/* Theme transitions — ease the page chrome when the theme switches.
   Scoped to a curated list of elements rather than * because:
   - color/background-color/border-color don't normally re-trigger on these,
     so the transition only fires when CSS vars change (i.e. theme switches);
   - applying transition: * to buttons/inputs would conflict with Bootstrap's
     existing hover/focus transitions. */
body,
.card, .card-header, .card-body,
.navbar, .site-footer,
.theme-card__preview,
.theme-card__name {
    transition: background-color 150ms ease,
                color            150ms ease,
                border-color     150ms ease;
}

/* Site footer — themed surface with a delineation border. Replaces Bootstrap's
   hardcoded .bg-light (which stays #f8f9fa regardless of theme and made the
   footer unreadable on dark themes). Falls back to --pp-bg on themes that
   don't define --pp-surface-alt so the footer always has a concrete color. */
.site-footer {
    background: var(--pp-surface-alt, var(--pp-bg));
    color: var(--pp-text);
    border-top: 1px solid var(--pp-border);
}

/* Theme picker grid (preferences page).
   Each .theme-card carries data-theme="<name>" so the [data-theme="..."]
   selectors in this file scope CSS vars to that card. The swatches inside
   then resolve var(--pp-*) using that theme's palette — no per-theme hex
   values need to be duplicated here. */
.theme-group-toggle {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
    padding: 0.5rem 0.25rem;
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--pp-border);
    color: var(--pp-text);
    text-align: left;
    cursor: pointer;
    margin-bottom: 0.5rem;
}
.theme-group-toggle:hover,
.theme-group-toggle:focus-visible {
    color: var(--pp-accent);
    outline: none;
}
.theme-group-chevron {
    display: inline-block;
    font-size: 0.75rem;
    line-height: 1;
    color: var(--pp-text-muted);
    transition: transform 150ms ease;
}
.theme-group-toggle[aria-expanded="true"] .theme-group-chevron {
    transform: rotate(90deg);
}
.theme-group-label {
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    color: var(--pp-text-muted);
    flex: 1;
}
.theme-group-toggle:hover .theme-group-label,
.theme-group-toggle:focus-visible .theme-group-label {
    color: var(--pp-accent);
}
.theme-group-count {
    font-size: 0.75rem;
    color: var(--pp-text-muted);
    padding: 0.1rem 0.45rem;
    border-radius: 999px;
    background: var(--pp-bg);
    border: 1px solid var(--pp-border);
    line-height: 1;
}
.theme-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
    gap: 0.5rem;
}
.theme-card {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0.5rem;
    padding: 0.625rem;
    background: var(--pp-surface);
    color: var(--pp-text);
    border: 1px solid var(--pp-border);
    border-radius: 0.5rem;
    cursor: pointer;
    text-align: left;
    /* Two-element selection ring: thin border stays on every card, accent
       box-shadow paints outside it on hover/selected (no layout flicker
       because box-shadow doesn't take part in the box model). */
    transition: background-color 150ms ease,
                color            150ms ease,
                border-color     130ms ease,
                box-shadow       130ms ease;
}
.theme-card:hover,
.theme-card:focus-visible {
    border-color: var(--pp-accent);
    box-shadow: 0 0 0 2px var(--pp-accent);
    outline: none;
}
.theme-card.is-selected {
    border-color: var(--pp-accent);
    box-shadow: 0 0 0 2px var(--pp-accent);
}
.theme-card__spectrum {
    display: block;
    width: 100%;
    height: 18px;
    border-radius: 0.25rem;
    border: 1px solid var(--pp-border);
}
.theme-card__name {
    font-size: 1rem;
    font-weight: 600;
    color: var(--pp-heading);
    line-height: 1.2;
}
.theme-card__tagline {
    font-size: 0.8rem;
    color: var(--pp-text);
    line-height: 1.3;
    opacity: 0.9;
}
.theme-card__check {
    position: absolute;
    bottom: 0.375rem;
    right: 0.5rem;
    width: 1.1rem;
    height: 1.1rem;
    /* Hidden by default; .is-saved (set by the AJAX submit handler, not by
       hover preview) shows it. Rendered on every card so the live-update
       JS just toggles a class instead of touching the DOM tree. */
    display: none;
    align-items: center;
    justify-content: center;
    font-size: 0.75rem;
    color: var(--pp-on-accent);
    background: var(--pp-accent);
    border-radius: 50%;
    line-height: 1;
}
.theme-card.is-saved .theme-card__check {
    display: flex;
}

/* Font-size picker — "A A A A" button group, each A drawn at its own scale
   so the visual hint matches the resulting size. */
.font-size-group {
    display: inline-flex;
    border: 1px solid var(--pp-border);
    border-radius: 0.5rem;
    overflow: hidden;
}
.font-size-btn {
    display: flex;
    align-items: baseline;
    justify-content: center;
    min-width: 3rem;
    padding: 0.5rem 0.75rem;
    background: var(--pp-surface);
    color: var(--pp-text);
    border: 0;
    border-right: 1px solid var(--pp-border);
    cursor: pointer;
    font-weight: 600;
    line-height: 1;
}
.font-size-btn:last-child { border-right: 0; }
.font-size-btn:hover,
.font-size-btn:focus-visible {
    background: var(--pp-bg);
    color: var(--pp-accent);
    outline: none;
}
.font-size-btn.is-selected {
    background: var(--pp-accent);
    color: var(--pp-on-accent);
}
/* Visual size hint — each "A" rendered at the size the option will apply,
   independent of the picker page's current root font-size. Using em on
   .font-size-btn__a inside a fixed-size button keeps the hint stable. */
.font-size-btn[data-font-size="small"]   .font-size-btn__a { font-size: 0.85rem; }
.font-size-btn[data-font-size="medium"]  .font-size-btn__a { font-size: 1rem; }
.font-size-btn[data-font-size="large"]   .font-size-btn__a { font-size: 1.2rem; }
.font-size-btn[data-font-size="x-large"] .font-size-btn__a { font-size: 1.4rem; }
