/* GFXstudio — shared account-page theme: dark charcoal background, green accent.
   (The control panel and output pages have their own dark full-bleed styling —
   this file is only for login/projects/account-facing pages.)

   Sidebar layout, button, and card treatments ported from
   Clubs.worldwaterskiers.com/new-build's public/assets/css/app.css — colors
   adapted to GFXstudio's own grey/green brand where Clubs used navy/blue.

   Palette below is pixel-sampled (Python/PIL, not eyeballed) from a DaVinci
   Resolve screenshot the user shared — bin tree, track headers, and timeline
   all sample out to the same #28282e panel tone, with near-black #090909
   seams between panels (Resolve's dividers are darker grout lines, not
   lighter borders) and a muted brick-red #963a34 for the V4/V5 track badges.
   Two earlier passes at this were eyeballed and came out too black/flat —
   these values are the real sampled ones. */

/* Inter's x-height/cap-height runs larger than San Francisco/Segoe UI at the same
   px size, so swapping it in for the system-ui stack reads visibly bigger even
   though every rem value is unchanged. Bootstrap's whole type + spacing scale is
   rem-based off the root, so nudging the root size down here rebalances Inter
   against the system font it's replacing without touching individual components. */
html {
    font-size: 97%;
}

:root {
    --gfx-bg: #18181a;          /* page canvas behind cards — darker than the panel, same family as the seam color */
    --gfx-panel: #28282e;       /* exact sample: bin tree / track-header / sidebar panel tone */
    --gfx-panel-alt: #38383e;   /* row-hover / selected-row shade, lighter than panel */
    --gfx-border: #0a0a0a;      /* exact sample: the seams between panels — darker than the panel, not lighter */
    --gfx-text: #d8d8d8;        /* primary text — Resolve's off-white, not pure #fff */
    --gfx-text-muted: #8f8f8f;  /* secondary/label text */
    --gfx-sidebar: #28282e;     /* media-pool tree background — same exact tone as --gfx-panel in the sample */
    /* Theme color — the one place to swap to try a different accent. Everything
       else (hover states, badges, tabs, focus rings) derives from this via
       color-mix() rather than its own hardcoded hex. */
    /* --gfx-accent / --gfx-accent-text / --gfx-link / --gfx-cta now live in
       brand.css (loaded before this file) -- ONE place to change the brand color. */
    --gfx-red: #963a34;         /* exact sample: V4/V5 track-header badge red */
    --gfx-blue: #3a5fcd;        /* text-clip blue — not re-sampled, no strong blue swatch in this shot */
    --gfx-tan: #b9b097;         /* exact sample: b-roll/text clip tan */
    --gfx-sidebar-w: 220px;
    /* Inter, loaded in includes/head.php — closest Google Font match to the system-ui/
       -apple-system/Segoe UI stack Bootstrap defaults to, so swapping it in reads as
       "native UI" rather than a branded typeface. Same fallback stack kept behind it
       in case the Google Fonts request is ever blocked. */
    --gfx-font: 'Inter', system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

body, .btn, .form-control, .form-select, .dropdown-menu {
    font-family: var(--gfx-font);
}

/* Dark checkerboard so a transparent PNG/SVG logo preview is visibly distinct from
   a solid-background image. Same pattern as media-library.php's .media-thumb-checker
   — shared here so any page can reuse it. */
/* Same two-tone checker as the Designer canvas's own transparency indicator
   (public/designer.php's #stage --checker-a/--checker-b: #ffffff/#e8e8e8) — kept in
   sync intentionally, so a thumbnail looks like the canvas it was captured from. */
.gfx-checker {
    background-image:
        linear-gradient(45deg, #e8e8e8 25%, transparent 25%), linear-gradient(-45deg, #e8e8e8 25%, transparent 25%),
        linear-gradient(45deg, transparent 75%, #e8e8e8 75%), linear-gradient(-45deg, transparent 75%, #e8e8e8 75%);
    background-size: 10px 10px;
    background-position: 0 0, 0 5px, 5px -5px, -5px 0px;
    background-color: #ffffff;
}

/* Shared list/grid card view — used by designs.php and themes.php so both catalog
   pages look and behave the same. Page-specific bits (e.g. designs.php's sortable
   table, tag chips) stay local to that page's own <style> block. */
.gfx-design-thumb-empty {
    background: var(--gfx-panel-alt); color: var(--gfx-text-muted); font-size: 1.75rem;
}
.gfx-thumb-preview-btn { cursor: zoom-in; }
.gfx-thumb-preview-large {
    width: 100%; aspect-ratio: 16 / 9; border-radius: 6px; overflow: hidden;
    display: flex; align-items: center; justify-content: center;
}
.gfx-thumb-preview-large img { width: 100%; height: 100%; object-fit: contain; display: block; }
.gfx-design-title-link { color: var(--gfx-link); font-weight: 600; text-decoration: none; }
.gfx-design-title-link:hover { text-decoration: underline; }

.gfx-view-toggle { display: inline-flex; border: 1px solid var(--gfx-border-soft, #4a4a50); border-radius: 6px; overflow: hidden; }
.gfx-view-toggle-btn {
    border: none; background: transparent; color: var(--gfx-text-muted); cursor: pointer;
    padding: .4rem .65rem; font-size: 1rem; line-height: 1; display: flex; align-items: center;
}
.gfx-view-toggle-btn + .gfx-view-toggle-btn { border-left: 1px solid var(--gfx-border-soft, #4a4a50); }
.gfx-view-toggle-btn:hover { color: var(--gfx-text); }
.gfx-view-toggle-btn.active { background: var(--gfx-cta, #4bde80); color: var(--gfx-cta-text, #0c2b16); }

.gfx-design-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 1rem; }
.gfx-design-card {
    background: var(--gfx-panel); border: 1px solid var(--gfx-border-soft, #4a4a50);
    border-radius: 8px; overflow: hidden; display: flex; flex-direction: column;
}
.gfx-design-card-thumb-wrap { position: relative; }
.gfx-design-card-thumb-link { display: block; }
.gfx-design-card-thumb {
    width: 100%; aspect-ratio: 16 / 9; display: flex; align-items: center; justify-content: center;
    background-size: 8px 8px !important; background-position: 0 0, 0 4px, 4px -4px, -4px 0px !important;
}
.gfx-design-card-thumb img { width: 100%; height: 100%; object-fit: contain; display: block; }
.gfx-design-card-thumb.gfx-design-thumb-empty { font-size: 2rem; }
.gfx-design-card-body { padding: .75rem; display: flex; flex-direction: column; gap: .35rem; flex: 1; }
.gfx-design-card-meta { display: flex; flex-wrap: wrap; gap: .35rem; align-items: center; font-size: .8rem; color: var(--gfx-text-muted); }
/* margin-top:auto pins this to the bottom of the card regardless of how much sits
   above it (badges/tags vary per design) — so every card in a row lines its date/
   actions up evenly instead of following wherever the content happens to end. */
.gfx-design-card-footer { display: flex; align-items: center; justify-content: space-between; margin-top: auto; padding-top: .25rem; }
.gfx-design-card-updated { font-size: .72rem; }
.gfx-design-card-actions { display: flex; align-items: center; gap: .4rem; opacity: 0; transition: opacity .15s; }
.gfx-design-card:hover .gfx-design-card-actions { opacity: 1; }

body {
    background-color: var(--gfx-bg);
    color: var(--gfx-text);
}

.app-navbar {
    background-color: #000;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 1030; /* Bootstrap's own fixed-top navbar tier — stays above .gfx-sidebar (100) and page content */
}

/* Pushes page content below the now-fixed navbar — every LOGGED-IN account-facing
   page's <main> sits directly after it in includes/head.php. Matches .gfx-sidebar's own
   hardcoded top:56px (below), so both line up with the navbar's real rendered height.
   Guest pages (.auth-main below) don't need this: their nav is sticky-top, not fixed, so
   it already occupies its own space in normal flow. */
main {
    margin-top: 56px;
}

/* Logged-out pages (login/forgot-password/reset-password/register) — vertically +
   horizontally centers the card in the remaining viewport height instead of it just
   sitting at the top, same treatment WWS/Clubs give their standalone auth pages. No
   margin-top compensation here (see main{} above) since includes/head.php gives these
   pages the same sticky-top nav as home/features/pricing/blog, not the dashboard's
   fixed one -- the nav already takes up real, in-flow space. */
.auth-main {
    margin-top: 0;
    min-height: 75vh;
    display: flex;
    align-items: center;
}
.auth-main > .row { width: 100%; }

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

a {
    color: var(--gfx-link);
}

.text-muted {
    color: var(--gfx-text-muted) !important;
}

/* Bootstrap gives .form-text its own color (near-black #212529 at 75% opacity) rather
   than inheriting from .text-muted — missed when this theme overrode .text-muted above,
   so every field-help caption on this page was rendering almost invisible on the dark
   background instead of the intended muted-grey. */
.form-text {
    color: #5b5b5b;
    font-size: .75rem;
}

/* ── Sidebar ─────────────────────────────────────────────────────────────── */
/* Fixed sidebar + margin-left content pane (not flexbox) — same structural
   pattern as Clubs' .sidebar/.main-content pairing. Matches Resolve's bin-tree
   panel shade rather than the old flat #3e3e3e. */

.gfx-sidebar {
    width: var(--gfx-sidebar-w);
    background: var(--gfx-sidebar);
    border-right: 1px solid var(--gfx-border);
    position: fixed;
    top: 56px; /* below .app-navbar */
    left: 0;
    bottom: 0;
    z-index: 100;
    padding: 1rem 0.75rem;
    /* Flex column so the version line (a plain sibling <div> after .gfx-sidebar-nav,
       see includes/head.php) sits pinned at the very bottom of the viewport instead
       of just trailing whatever the nav list's last item happens to be — the nav
       list is the only part that scrolls internally if it ever grows past the
       available height. */
    display: flex;
    flex-direction: column;
}

.gfx-sidebar-nav {
    flex: 1 1 auto;
    flex-wrap: nowrap; /* override Bootstrap .nav's flex-wrap:wrap, which otherwise lays overflow out as new columns instead of scrolling */
    min-height: 0; /* let it shrink below content height so overflow-y can actually scroll */
    overflow-y: auto;
}

.gfx-main {
    margin-left: var(--gfx-sidebar-w);
}

/* Section labels (MAIN / PLATFORM / SETTINGS / etc.) — one shared class so every
   group heading in the sidebar is the same size/weight/spacing, instead of the
   "Settings" label being the only one with its own one-off inline style. */
.gfx-sidebar-heading {
    padding: 0 1rem .4rem;
    margin-top: 1.85rem;
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
    color: var(--gfx-text-muted);
}
.gfx-sidebar-heading:first-child { margin-top: 0; }

.gfx-sidebar-nav .nav-link {
    color: var(--gfx-text-muted);
    padding: .45rem 1rem;
    border-radius: 6px;
    margin-bottom: 1px;
    font-size: .875rem;
    display: flex;
    align-items: center;
    gap: .5rem;
    transition: background .15s, color .15s;
}

.gfx-sidebar-nav .nav-link:hover,
.gfx-sidebar-nav .nav-link.active {
    background: rgba(255, 255, 255, .08);
    color: var(--gfx-text);
}

/* Nested sub-links under a parent nav item (e.g. one entry per Email Template) —
   ported from Clubs.worldwaterskiers.com/new-build's .nav-sub-link: indented past the
   parent's icon, smaller, only rendered while the parent section is open. The chevron
   on the parent flips down when open. */
.gfx-sidebar-nav .nav-link .gfx-nav-chevron {
    margin-left: auto;
    font-size: .65rem;
    opacity: .5;
}
.gfx-sidebar-nav .nav-sub-link {
    display: flex;
    align-items: center;
    color: var(--gfx-text-muted);
    opacity: .85;
    padding: .32rem 1rem .32rem 2.4rem;
    border-radius: 6px;
    margin-bottom: 1px;
    font-size: .8rem;
    text-decoration: none;
    transition: background .15s, color .15s;
}
.gfx-sidebar-nav .nav-sub-link:hover,
.gfx-sidebar-nav .nav-sub-link.active {
    background: rgba(255, 255, 255, .08);
    color: var(--gfx-text);
    opacity: 1;
}

/* ── Buttons ─────────────────────────────────────────────────────────────── */

.btn { --bs-btn-border-width: 2px; }

.btn-accent {
    background-color: var(--gfx-accent);
    border-color: var(--gfx-accent);
    color: var(--gfx-accent-text);
    font-weight: 600;
}

/* Derived from --gfx-accent rather than a second hardcoded hex — swapping the
   theme color in :root (see the comment up there) re-themes hover for free. */
.btn-accent:hover {
    background-color: color-mix(in srgb, var(--gfx-accent) 85%, #000);
    border-color: color-mix(in srgb, var(--gfx-accent) 85%, #000);
    color: var(--gfx-accent-text);
}

.btn-secondary {
    --bs-btn-bg: var(--gfx-panel-alt);
    --bs-btn-border-color: var(--gfx-border);
    --bs-btn-color: var(--gfx-text);
    --bs-btn-hover-bg: #333335;
    --bs-btn-hover-border-color: var(--gfx-border);
    --bs-btn-hover-color: var(--gfx-text);
    --bs-btn-active-bg: #333335;
    --bs-btn-active-border-color: var(--gfx-border);
    --bs-btn-active-color: var(--gfx-text);
}

.btn-outline-secondary {
    --bs-btn-color: var(--gfx-text-muted);
    --bs-btn-bg: transparent;
    --bs-btn-border-color: var(--gfx-border);
    --bs-btn-border-radius: 20px;
    --bs-btn-font-weight: 500;
    --bs-btn-font-size: .82rem;
    --bs-btn-hover-color: var(--gfx-text);
    --bs-btn-hover-bg: var(--gfx-panel-alt);
    --bs-btn-hover-border-color: var(--gfx-border);
    --bs-btn-active-color: var(--gfx-text);
    --bs-btn-active-bg: var(--gfx-panel-alt);
    --bs-btn-active-border-color: var(--gfx-border);
    --bs-btn-disabled-color: var(--gfx-text-muted);
    --bs-btn-disabled-border-color: var(--gfx-border);
}

/* Unlike .btn-outline-secondary above (pill-shaped, smaller text — used for compact
   inline actions like "Browse Library"), this is for a secondary action that needs to
   sit shoulder-to-shoulder with a primary .btn-accent button (e.g. Cancel next to Save)
   and match its size/shape exactly — so it deliberately does NOT touch border-radius/
   font-size/font-weight, only recolors Bootstrap's default outline-dark to fit the dark
   theme (filled dark panel instead of Bootstrap's default white-with-black-border). */
.btn-outline-dark {
    --bs-btn-color: var(--gfx-text);
    --bs-btn-bg: var(--gfx-panel-alt);
    --bs-btn-border-color: var(--gfx-border);
    --bs-btn-font-weight: 600;
    --bs-btn-hover-color: var(--gfx-text);
    --bs-btn-hover-bg: color-mix(in srgb, var(--gfx-panel-alt) 85%, white);
    --bs-btn-hover-border-color: var(--gfx-border);
    --bs-btn-active-color: var(--gfx-text);
    --bs-btn-active-bg: var(--gfx-panel-alt);
    --bs-btn-active-border-color: var(--gfx-border);
    --bs-btn-disabled-color: var(--gfx-text-muted);
    --bs-btn-disabled-bg: var(--gfx-panel);
    --bs-btn-disabled-border-color: var(--gfx-border);
}

.btn-outline-accent {
    --bs-btn-color: var(--gfx-accent);
    --bs-btn-border-color: var(--gfx-accent);
    --bs-btn-bg: transparent;
    --bs-btn-font-weight: 600;
    --bs-btn-hover-color: var(--gfx-accent-text);
    --bs-btn-hover-bg: var(--gfx-accent);
    --bs-btn-hover-border-color: var(--gfx-accent);
    --bs-btn-active-color: var(--gfx-accent-text);
    --bs-btn-active-bg: var(--gfx-accent);
    --bs-btn-active-border-color: var(--gfx-accent);
}

.btn-outline-danger {
    --bs-btn-color: var(--gfx-red);
    --bs-btn-border-color: var(--gfx-red);
    --bs-btn-hover-bg: var(--gfx-red);
    --bs-btn-hover-border-color: var(--gfx-red);
}

.btn-link { color: var(--gfx-link); }

/* ── Account menu (navbar top-right) ────────────────────────────────────────── */

.account-menu-btn {
    background: transparent;
    border: 1px solid transparent;
    color: #fff;
    font-size: .875rem;
    display: inline-flex;
    align-items: center;
    gap: .4rem;
}
.account-menu-btn:hover,
.account-menu-btn:focus {
    background: rgba(255, 255, 255, .08);
    color: #fff;
}
.account-menu-btn i { font-size: 1.1rem; }
.account-menu-btn::after { margin-left: .3rem; }
.account-avatar {
    width: 26px; height: 26px; border-radius: 50%; flex-shrink: 0;
    display: inline-flex; align-items: center; justify-content: center;
    color: #fff; font-size: .7rem; font-weight: 700; letter-spacing: .02em;
}

.account-menu {
    background: var(--gfx-panel);
    border: 1px solid var(--gfx-border);
    min-width: 220px;
    padding: 0;
    overflow: hidden;
}
.account-menu-email {
    padding: .65rem 1rem;
    color: var(--gfx-text-muted);
    font-size: .82rem;
    word-break: break-all;
}
.account-menu .dropdown-divider { border-color: var(--gfx-border); margin: 0; }
.account-menu .dropdown-item {
    color: var(--gfx-text);
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .55rem 1rem;
    font-size: .9rem;
}
.account-menu .dropdown-item i { font-size: 1rem; color: var(--gfx-text-muted); }
.account-menu .dropdown-item:hover,
.account-menu .dropdown-item:focus {
    background: var(--gfx-panel-alt);
    color: var(--gfx-text);
}
.account-menu .dropdown-item.account-menu-danger,
.account-menu .dropdown-item.account-menu-danger i { color: var(--gfx-red); }
.account-menu .dropdown-item.account-menu-danger:hover { background: color-mix(in srgb, var(--gfx-red) 15%, transparent); }

/* ── Bare icon buttons (edit / delete) — ported from WorldWaterSkiers NEW's
   public/assets/css/admin.css .btn-edit/.btn-delete: no circle/border, just the
   icon, colored on hover — instead of this project's own btn-sm btn-outline-*
   pill treatment for the same row actions.
   Usage: <button class="btn-edit" title="Edit"><i class="bi bi-pencil"></i></button>
          <button class="btn-delete" title="Delete"><i class="bi bi-trash"></i></button> */
.btn-edit,
.btn-delete {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: none;
    color: var(--gfx-text-muted);
    padding: .25rem .35rem;
    border-radius: 5px;
    line-height: 1;
    cursor: pointer;
    text-decoration: none;
    transition: color .15s;
    font-size: 1rem;
}
.btn-edit:hover   { color: var(--gfx-link); }
.btn-delete:hover { color: var(--gfx-red); }

/* ── Cards ───────────────────────────────────────────────────────────────── */
/* Applied to Bootstrap's own .card (Clubs' equivalent is a separate .stat-card
   class, but this project already uses .card directly, so the override goes
   straight onto it instead of introducing a second class name). */

.card {
    background-color: var(--gfx-panel);
    border: 1px solid var(--gfx-border);
    border-radius: 10px;
    color: var(--gfx-text);
    overflow: hidden; /* clips flush-edge content (e.g. a table in a p-0 card) to the rounded corners */
}

.form-control-color {
    width: 4rem;
    padding: 0.25rem;
}

/* ── Tables ──────────────────────────────────────────────────────────────── */
/* Bootstrap's .table inherits from CSS vars it sets itself, so a plain color
   override on the parent isn't enough on dark backgrounds — set its own vars. */

.table {
    --bs-table-bg: transparent;
    --bs-table-color: var(--gfx-text);
    --bs-table-striped-bg: var(--gfx-panel-alt);
    --bs-table-hover-bg: var(--gfx-panel-alt);
    --bs-table-hover-color: var(--gfx-text);
    --bs-table-border-color: var(--gfx-border);
    font-size: .875rem;
}

.table thead th {
    color: var(--gfx-text-muted);
    font-size: .78rem;
    text-transform: uppercase;
    letter-spacing: .04em;
    font-weight: 700;
    border-bottom-color: var(--gfx-border);
}

/* Bootstrap's .border-bottom utility defaults to a light grey (--bs-border-color-translucent-ish)
   meant for light backgrounds — reads as a near-white line on this dark theme (e.g. the
   row dividers between changelog entries) without this. */
.border-bottom {
    border-bottom-color: var(--gfx-border) !important;
}

/* ── Forms ───────────────────────────────────────────────────────────────── */

.form-control,
.form-select {
    background-color: var(--gfx-panel-alt);
    border-color: var(--gfx-border);
    color: var(--gfx-text);
}
/* Bootstrap's default chevron is a dark-gray SVG (#343a40) meant for a light
   background — on this app's permanent dark theme it's nearly invisible, so a
   <select> reads as a plain text box instead of an obvious dropdown. Same chevron
   path, just redrawn in a light tone that actually shows up on --gfx-panel-alt. */
.form-select {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%238f8f98' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
}

.form-control:focus,
.form-select:focus {
    background-color: var(--gfx-panel-alt);
    border-color: var(--gfx-link);
    color: var(--gfx-text);
    box-shadow: 0 0 0 .2rem color-mix(in srgb, var(--gfx-link) 25%, transparent);
}

.form-control:disabled,
.form-control[readonly] {
    background-color: var(--gfx-panel);
    color: var(--gfx-text-muted);
}

.form-check-input {
    background-color: var(--gfx-panel-alt);
    border-color: var(--gfx-border);
}

.form-check-input:checked {
    background-color: var(--gfx-link);
    border-color: var(--gfx-link);
}

/* ── Modals ──────────────────────────────────────────────────────────────── */

.modal-content {
    background-color: var(--gfx-panel);
    color: var(--gfx-text);
    border: 1px solid var(--gfx-border);
}

.modal-header,
.modal-footer {
    border-color: var(--gfx-border);
}

.btn-close {
    filter: invert(1) grayscale(1) brightness(1.8);
}

/* ── Badges ──────────────────────────────────────────────────────────────── */
/* Ported from Clubs' app.css: rounded pill treatment for any semantic badge,
   colors derived from currentColor so it covers every variant without a rule
   per color. bg-primary uses GFXstudio's green instead of Clubs' blue. Tints
   mix with --gfx-panel instead of white now that the surface underneath is
   dark — the old `currentColor 15%, #fff` mix went near-invisible here. */

.badge[class*="-subtle"] {
    border-radius: 50rem !important;
    border: 1.5px solid currentColor;
    background-color: color-mix(in srgb, currentColor 20%, var(--gfx-panel)) !important;
    font-weight: 700;
    padding: .3em .75em;
}

.badge.bg-success, .badge.bg-danger, .badge.bg-warning, .badge.bg-info,
.badge.bg-primary, .badge.bg-secondary, .badge.bg-dark, .badge.bg-light,
.badge.bg-purple, .badge.bg-teal, .badge.bg-pink, .badge.bg-indigo, .badge.bg-orange {
    border-radius: 50rem !important;
    font-weight: 700;
    padding: .3em .75em;
}
.badge.bg-success  { background-color: color-mix(in srgb, #4bbf73 20%, var(--gfx-panel)) !important; border: 1.5px solid #4bbf73; color: #6fdb95 !important; }
.badge.bg-danger   { background-color: color-mix(in srgb, var(--gfx-red) 25%, var(--gfx-panel)) !important; border: 1.5px solid var(--gfx-red); color: #e2837e !important; }
.badge.bg-warning  { background-color: color-mix(in srgb, #e5a54b 20%, var(--gfx-panel)) !important; border: 1.5px solid #e5a54b; color: #f0bf7c !important; }
.badge.bg-info     { background-color: color-mix(in srgb, var(--gfx-blue) 25%, var(--gfx-panel)) !important; border: 1.5px solid var(--gfx-blue); color: #8fa8ec !important; }
.badge.bg-primary  { background-color: color-mix(in srgb, var(--gfx-link) 20%, var(--gfx-panel)) !important; border: 1.5px solid var(--gfx-link); color: var(--gfx-link) !important; }
.badge.bg-secondary{ background-color: color-mix(in srgb, var(--gfx-text-muted) 20%, var(--gfx-panel)) !important; border: 1.5px solid var(--gfx-text-muted); color: #c2c2c6 !important; }
.badge.bg-dark     { background-color: var(--gfx-panel-alt) !important; border: 1.5px solid var(--gfx-border); color: var(--gfx-text) !important; }
.badge.bg-light    { background-color: var(--gfx-panel-alt) !important; border: 1.5px solid var(--gfx-border); color: var(--gfx-text-muted) !important; }
.badge.bg-purple   { background-color: color-mix(in srgb, #7c3aed 25%, var(--gfx-panel)) !important; border: 1.5px solid #7c3aed; color: #ac8bf7 !important; }
.badge.bg-teal     { background-color: color-mix(in srgb, var(--gfx-tan) 25%, var(--gfx-panel)) !important; border: 1.5px solid var(--gfx-tan); color: var(--gfx-tan) !important; }
.badge.bg-pink     { background-color: color-mix(in srgb, #db2777 25%, var(--gfx-panel)) !important; border: 1.5px solid #db2777; color: #ee7fb3 !important; }
.badge.bg-indigo   { background-color: color-mix(in srgb, #4f46e5 25%, var(--gfx-panel)) !important; border: 1.5px solid #4f46e5; color: #948cf0 !important; }
.badge.bg-orange   { background-color: color-mix(in srgb, #ea580c 25%, var(--gfx-panel)) !important; border: 1.5px solid #ea580c; color: #f19c68 !important; }

/* ── Input placeholders ─────────────────────────────────────────────────── */

.form-control::placeholder,
.form-select::placeholder,
textarea::placeholder,
input::placeholder {
    color: #5a5a5e;
    opacity: 1;
}

.form-label {
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--gfx-text-muted);
    margin-bottom: .3rem;
}

/* ── Global tabs ─────────────────────────────────────────────────────────── */
/* Not used anywhere yet, ported so any future nav-tabs/nav-pills UI already
   matches Clubs' look instead of stock Bootstrap. */

.nav-pills .nav-link         { background: var(--gfx-panel-alt); color: var(--gfx-text-muted); border-radius: 50rem !important; font-size: .875rem; }
.nav-pills .nav-link:hover   { background: #333335; color: var(--gfx-text); }
.nav-pills .nav-link.active,
.nav-pills .show > .nav-link { background: color-mix(in srgb, var(--gfx-link) 20%, var(--gfx-panel)) !important; color: var(--gfx-link) !important; }

.nav-tabs { border-bottom: none; flex-wrap: wrap; gap: .5rem; }
.nav-tabs .nav-item { margin-bottom: 0; }
.nav-tabs .nav-link {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    border: 2px solid var(--gfx-border);
    border-radius: 20px;
    background: var(--gfx-panel);
    color: var(--gfx-text-muted);
    padding: .28rem .9rem;
    font-weight: 500;
    font-size: .82rem;
    transition: background-color .15s, color .15s, border-color .15s;
}
.nav-tabs .nav-link:hover { background: var(--gfx-panel-alt); color: var(--gfx-text); }
.nav-tabs .nav-link.active,
.nav-tabs .nav-link.active:hover {
    background: var(--gfx-link);
    border-color: var(--gfx-link);
    color: var(--gfx-accent-text);
}

/* ── Password show/hide toggle (assets/js/password-toggle.js) ────────────
   Ported from WorldWaterSkiers NEW's .wws-password-field, renamed .gfx-*.
   Usage: <div class="gfx-password-field">
            <input type="password" class="form-control">
            <i class="bi bi-eye gfx-password-toggle"></i>
          </div> */
.gfx-password-field { position: relative; }
.gfx-password-field .form-control { padding-right: 2.5rem; }
.gfx-password-toggle {
    position: absolute;
    right: 12px;
    top: 50%;
    transform: translateY(-50%);
    cursor: pointer;
    color: var(--gfx-text-muted);
    user-select: none;
}

/* ── Tabs + Starter/Library (assets/js/starter-library.js) ───────────────────
   Both /designs and /themes split into "mine" and "library" panes: the library
   holds the admin-built starter graphics any account can copy into its own. Shared
   here rather than duplicated in each page's own <style> block, same reasoning as
   the list/grid card rules at the top of this file. */

.gfx-tabs { display: flex; gap: .25rem; border-bottom: 1px solid var(--gfx-border-soft, #4a4a50); margin-bottom: 1.25rem; }
.gfx-tab {
    border: none; background: transparent; color: var(--gfx-text-muted); cursor: pointer;
    padding: .55rem 1rem; font-size: .92rem; font-weight: 600; border-bottom: 2px solid transparent;
    margin-bottom: -1px; display: flex; align-items: center; gap: .45rem;
}
.gfx-tab:hover { color: var(--gfx-text); }
.gfx-tab.active { color: var(--gfx-link); border-bottom-color: var(--gfx-link); }
.gfx-tab-count {
    background: var(--gfx-panel-alt); color: var(--gfx-text-muted);
    border-radius: 999px; padding: 1px 7px; font-size: .72rem; font-weight: 700;
}
.gfx-tab.active .gfx-tab-count { background: var(--gfx-link); color: var(--gfx-accent-text); }

/* Starter strip — the quick-start row above a user's own list. Deliberately a
   horizontally scrolling strip rather than a wrapping grid: it sits on top of the
   page the user actually came for, so it has to stay one bounded row however many
   starters exist. The full browsable version is the Library tab. */
.gfx-starter-strip {
    padding: 0; margin-bottom: 2.5rem;
}
.gfx-starter-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; margin-bottom: .65rem; }
.gfx-starter-title { font-weight: 600; font-size: .95rem; margin: 0; }
.gfx-starter-sub { font-size: .78rem; color: var(--gfx-text-muted); margin: .1rem 0 0; }
.gfx-starter-close {
    border: none; background: transparent; color: var(--gfx-text-muted); cursor: pointer;
    font-size: 1rem; line-height: 1; padding: .15rem .3rem; flex-shrink: 0;
}
.gfx-starter-close:hover { color: var(--gfx-text); }
.gfx-starter-restore {
    border: none; background: transparent; color: var(--gfx-text-muted); cursor: pointer;
    font-size: .8rem; padding: 0; margin-bottom: 1rem; text-decoration: underline;
}
.gfx-starter-restore:hover { color: var(--gfx-text); }

.gfx-starter-scroll-wrap { display: flex; align-items: center; gap: .5rem; }
.gfx-starter-scroll {
    display: flex; gap: .85rem; overflow-x: auto; scroll-behavior: smooth;
    scrollbar-width: none; flex: 1; min-width: 0; padding: .15rem;
}
.gfx-starter-scroll::-webkit-scrollbar { display: none; }
.gfx-starter-nav {
    flex: 0 0 auto; width: 28px; height: 28px; border-radius: 50%; border: none;
    background: var(--gfx-panel-alt); color: var(--gfx-text); display: flex;
    align-items: center; justify-content: center; cursor: pointer;
}
.gfx-starter-nav:hover { background: var(--gfx-cta, #4bde80); color: var(--gfx-cta-text, #0c2b16); }

.gfx-starter-card {
    flex: 0 0 auto; width: 190px; background: var(--gfx-panel-alt);
    border: 1px solid var(--gfx-border-soft, #4a4a50); border-radius: 8px; overflow: hidden;
    display: flex; flex-direction: column; text-align: left;
}
.gfx-starter-card-thumb {
    width: 100%; aspect-ratio: 16 / 9; display: flex; align-items: center; justify-content: center;
    background-size: 8px 8px !important; background-position: 0 0, 0 4px, 4px -4px, -4px 0px !important;
}
.gfx-starter-card-thumb img { width: 100%; height: 100%; object-fit: contain; display: block; }
.gfx-starter-card-body { padding: .55rem .65rem .65rem; display: flex; flex-direction: column; gap: .3rem; flex: 1; }
.gfx-starter-card-name { font-weight: 600; font-size: .85rem; line-height: 1.25; }
.gfx-starter-card-meta { font-size: .72rem; color: var(--gfx-text-muted); display: flex; flex-wrap: wrap; gap: .3rem; align-items: center; }
/* margin-top:auto pins this to the card's bottom edge regardless of how much sits
   above it, same convention as .gfx-design-card-footer. */
.gfx-starter-card-footer { display: flex; align-items: center; justify-content: space-between; gap: .5rem; margin-top: auto; padding-top: .3rem; }

/* Round add FAB, right-aligned in the card's own footer row. Same green outline as
   .gfx-add-btn, just a circle instead of a pill and icon-only (see starter-library.js's
   iconOnly guard on why its innerHTML swaps stay icon-only through the click/added
   states). */
.gfx-starter-add {
    flex: 0 0 auto; width: 24px; height: 24px; border-radius: 50%;
    border: 1px solid var(--gfx-cta, #4bde80); background: transparent; color: var(--gfx-cta, #4bde80);
    display: flex; align-items: center; justify-content: center; cursor: pointer;
    font-size: .72rem;
}
.gfx-starter-add:hover:not(:disabled) { background: var(--gfx-cta, #4bde80); color: var(--gfx-cta-text, #0c2b16); }
.gfx-starter-add:disabled { opacity: .6; cursor: default; }
.gfx-starter-add.gfx-added { border-color: var(--gfx-border-soft, #4a4a50); color: var(--gfx-text-muted); }
.gfx-starter-add.gfx-added:hover:not(:disabled) { background: var(--gfx-panel-alt); color: var(--gfx-text); }

/* The add button carries its own added//busy states rather than the card doing it, so
   the same markup works in the strip and in the Library's table rows and grid cards. */
.gfx-add-btn {
    border: 1px solid var(--gfx-cta, #4bde80); background: transparent; color: var(--gfx-cta, #4bde80);
    border-radius: 6px; padding: .3rem .6rem; font-size: .76rem; font-weight: 600; cursor: pointer;
    white-space: nowrap; display: inline-flex; align-items: center; gap: .35rem; margin-top: auto;
}
.gfx-add-btn:hover:not(:disabled) { background: var(--gfx-cta, #4bde80); color: var(--gfx-cta-text, #0c2b16); }
.gfx-add-btn:disabled { opacity: .6; cursor: default; }
/* "Already in your account" — still clickable on purpose (a second copy is a
   legitimate way to start a variant), just visibly de-emphasised so it doesn't read
   as the obvious next click. */
.gfx-add-btn.gfx-added { border-color: var(--gfx-border-soft, #4a4a50); color: var(--gfx-text-muted); }
.gfx-add-btn.gfx-added:hover:not(:disabled) { background: var(--gfx-panel-alt); color: var(--gfx-text); }

.gfx-starter-swatches { display: inline-flex; gap: 3px; }
.gfx-starter-swatch { width: 11px; height: 11px; border-radius: 2px; border: 1px solid var(--gfx-border-soft, #4a4a50); }

/* ── Admin Dashboard (public/dashboard.php) ──────────────────────────────────── */

.gfx-stat-card { position: relative; overflow: hidden; }
.gfx-stat-icon {
    position: absolute; top: .75rem; right: .75rem; width: 38px; height: 38px; border-radius: 9px;
    display: flex; align-items: center; justify-content: center; font-size: 1.05rem;
}
.gfx-stat-icon-users    { background: color-mix(in srgb, var(--gfx-accent) 18%, transparent); color: var(--gfx-accent); }
.gfx-stat-icon-projects { background: color-mix(in srgb, #3a5fcd 18%, transparent); color: #6d8bff; }
.gfx-stat-icon-designs  { background: color-mix(in srgb, #b9b097 22%, transparent); color: #d8cba9; }
.gfx-stat-icon-themes   { background: color-mix(in srgb, #963a34 22%, transparent); color: #e0857e; }
.gfx-stat-delta { font-size: .76rem; color: var(--gfx-cta, #4bde80); margin-top: .2rem; }
.gfx-stat-delta i { font-size: .95rem; vertical-align: -2px; }

/* Signups bar chart — plain flex bars, no chart library (consistent with the rest of
   this app's hand-rolled widgets, e.g. the theme thumbnail carousel). Bars grow from a
   fixed-height track via a percentage height on the fill div, min 3% so a zero week is
   still a visible sliver rather than invisible. */
.gfx-bar-chart { display: flex; align-items: flex-end; gap: .6rem; height: 140px; }
.gfx-bar-chart-col { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; height: 100%; }
.gfx-bar-chart-value { font-size: .72rem; color: var(--gfx-text-muted); margin-bottom: .25rem; min-height: 1em; }
.gfx-bar-chart-bar {
    width: 100%; max-width: 34px; border-radius: 5px 5px 2px 2px;
    background: linear-gradient(180deg, var(--gfx-cta, #4bde80), color-mix(in srgb, var(--gfx-cta, #4bde80) 55%, transparent));
    transition: height .3s ease;
}
.gfx-bar-chart-label { font-size: .7rem; color: var(--gfx-text-muted); margin-top: .4rem; white-space: nowrap; }

.gfx-activity-list { display: flex; flex-direction: column; }
.gfx-activity-item {
    display: flex; align-items: center; gap: .65rem; padding: .55rem 0;
    border-bottom: 1px solid var(--gfx-border); text-decoration: none; color: inherit;
}
.gfx-activity-item:last-child { border-bottom: none; }
.gfx-activity-item:hover .gfx-activity-text { color: var(--gfx-link); }
.gfx-activity-icon {
    flex: 0 0 auto; width: 30px; height: 30px; border-radius: 50%; display: flex;
    align-items: center; justify-content: center; font-size: .85rem;
}
.gfx-activity-icon-user    { background: color-mix(in srgb, var(--gfx-accent) 18%, transparent); color: var(--gfx-accent); }
.gfx-activity-icon-project { background: color-mix(in srgb, #3a5fcd 18%, transparent); color: #6d8bff; }
.gfx-activity-text { flex: 1; font-size: .85rem; min-width: 0; }
.gfx-activity-time { font-size: .74rem; flex: 0 0 auto; }

.gfx-status-pills { display: flex; flex-direction: column; gap: .5rem; }
.gfx-status-pill { display: flex; align-items: center; gap: .5rem; font-size: .85rem; }
.gfx-status-pill strong { margin-left: auto; }
.gfx-status-dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; }
.gfx-status-dot-draft    { background: var(--gfx-text-muted); }
.gfx-status-dot-active   { background: var(--gfx-cta, #4bde80); }
.gfx-status-dot-archived { background: var(--gfx-red, #963a34); }

.gfx-status-row { display: flex; align-items: center; gap: .75rem; }
.gfx-live-dot { flex: 0 0 auto; width: 12px; height: 12px; border-radius: 50%; position: relative; }
.gfx-live-dot-up { background: var(--gfx-cta, #4bde80); box-shadow: 0 0 0 0 color-mix(in srgb, var(--gfx-accent) 55%, transparent); animation: gfx-pulse 2s infinite; }
.gfx-live-dot-down { background: var(--gfx-red, #963a34); }
@keyframes gfx-pulse {
    0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--gfx-accent) 55%, transparent); }
    70%  { box-shadow: 0 0 0 8px rgba(75, 222, 128, 0); }
    100% { box-shadow: 0 0 0 0 rgba(75, 222, 128, 0); }
}

.gfx-attn-item {
    display: flex; align-items: center; gap: .55rem; padding: .5rem .6rem; border-radius: 8px;
    font-size: .85rem; text-decoration: none; color: inherit;
}
.gfx-attn-warn { background: color-mix(in srgb, #d9a441 16%, transparent); color: #e8b955; }
.gfx-attn-warn:hover { background: color-mix(in srgb, #d9a441 26%, transparent); }
.gfx-attn-clear { color: var(--gfx-text-muted); }
.gfx-attn-clear i { color: var(--gfx-cta, #4bde80); }

.gfx-quick-actions { display: flex; flex-direction: column; gap: .35rem; }
.gfx-quick-action {
    display: flex; align-items: center; gap: .6rem; padding: .55rem .65rem; border-radius: 8px;
    font-size: .85rem; color: var(--gfx-text); text-decoration: none; background: var(--gfx-panel-alt);
}
.gfx-quick-action i { color: var(--gfx-link); width: 1.1rem; text-align: center; }
.gfx-quick-action:hover { background: var(--gfx-cta, #4bde80); color: var(--gfx-cta-text, #0c2b16); }
.gfx-quick-action:hover i { color: inherit; }

/* Admin dashboard's Software Survey donuts (Chart.js) — see
   assets/js/dashboard-survey-charts.js, which reads these swatch/legend classes to keep
   the legend colors in sync with whatever palette the chart actually drew. */
.gfx-donut-wrap { display: flex; align-items: center; gap: 1.1rem; }
.gfx-donut-canvas { position: relative; width: 92px; height: 92px; flex: none; }
.gfx-donut-legend { display: flex; flex-direction: column; gap: .4rem; min-width: 0; flex: 1; }
.gfx-donut-legend-row { display: flex; align-items: center; gap: .5rem; font-size: .82rem; }
.gfx-donut-swatch { width: 9px; height: 9px; border-radius: 50%; flex: none; }
.gfx-donut-legend-label { color: var(--gfx-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; }
.gfx-donut-legend-count { color: var(--gfx-text-muted); font-variant-numeric: tabular-nums; flex: none; }
