/* =====================================================================
 *  cb-components.css  —  shared component layer.
 *
 *  Was design-skins.css. The design LANGUAGES (atelier/halo/kinetik) have
 *  been removed; the site now has one design (chicabate-os.css) and two
 *  palettes (heat | plasma).
 *
 *  What remains here is NOT skin CSS — it is core structure that 39 pages
 *  depend on, and it is why the old file could not simply be deleted:
 *
 *    .avatar-dropdown / .user-avatar-section / .header-right
 *        the header cluster + avatar dropdown  (header-user.js, 34 pages)
 *    nav.hdr-member / nav.hdr-admin
 *        the member and admin nav bars
 *    .modal-content / .modal-body-scroll
 *        modal scroll containment (theme.js containModalScroll() needs it)
 *    .cb-switch
 *        the toggle switches used across the admin
 *    .atelier-dash
 *        the dashboard bento layout — hardcoded in the markup of
 *        admindashboard / modeldashboard / userdashboard, NOT design-gated.
 *        The name is historical; it is the live dashboard for everyone.
 *
 *  Everything here paints from the --primary/--secondary/--accent contract,
 *  so it adopts the active palette automatically with no changes.
 * ===================================================================== */

/* ---- Atelier: dashboards → "Bento II" profile-cover layout ---------- *
 * Under data-design="atelier" the default dashboard structure is hidden and
 * the .atelier-dash bento takes over: a profile-cover signature cell, live
 * stat metrics, an activity pulse, a content strip and an action console —
 * all fed from the real stat/notification values by the mirror script.
 * Both dashboards use .ad-replace-all; the admin adds a .b-admin console. */
.atelier-dash { display: none; }

.atelier-dash .b-head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin: 6px 0 20px; }
.atelier-dash .b-head .bk { font-family: var(--cb-sans); font-size: 11px; letter-spacing: .3em; text-transform: uppercase; color: rgba(var(--accent-rgb, 212,175,55), .82); }
.atelier-dash .b-head h1 { font-family: var(--cb-serif); font-weight: 600; font-size: clamp(28px, 3vw, 44px); margin: 4px 0 0; letter-spacing: -.01em; color: #f4eef0; }
.atelier-dash .b-head h1 em { font-style: italic; color: var(--accent); }
.atelier-dash .b-today { font-family: var(--cb-sans); font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: rgba(244,238,240,.5); }

.atelier-dash .bento { display: grid; gap: 16px; grid-template-columns: 1.45fr 1fr 1fr;
    grid-template-areas: 'cover views admirers' 'cover earn earn' 'pulse film film' 'dock dock dock'; }
.atelier-dash.has-admin .bento { grid-template-areas: 'cover views admirers' 'cover earn earn' 'pulse film film' 'admin admin admin' 'dock dock dock'; }
.atelier-dash .b-cell { position: relative; border: 1px solid var(--cb-hair); border-radius: 18px; background: rgba(255,255,255,.028); padding: 22px 24px; overflow: hidden; transition: transform .3s cubic-bezier(.2,.7,.2,1), border-color .3s, background .3s; }
.atelier-dash .b-cell:hover { transform: translateY(-3px); border-color: rgba(var(--accent-rgb, 212,175,55), .5); background: rgba(255,255,255,.05); }
.atelier-dash .b-eyebrow { font-family: var(--cb-sans); font-size: 10px; letter-spacing: .32em; text-transform: uppercase; color: rgba(244,238,240,.52); font-weight: 500; display: block; }
.atelier-dash .b-num { font-family: var(--cb-serif); font-variant-numeric: tabular-nums; font-weight: 500; color: #f4eef0; line-height: .9; }

.atelier-dash .b-cover { grid-area: cover; display: flex; flex-direction: column; justify-content: space-between; min-height: 330px; }
.atelier-dash .b-cbg { position: absolute; right: -70px; top: -70px; width: 280px; height: 280px; border-radius: 50%; pointer-events: none; background: radial-gradient(circle, rgba(var(--primary-rgb, 179,20,50), .5), transparent 62%); filter: blur(10px); }
.atelier-dash .b-cover .b-top { display: flex; gap: 20px; align-items: center; position: relative; }
.atelier-dash .b-avatar { flex: 0 0 auto; width: 92px; height: 92px; border-radius: 50%; display: grid; place-items: center; background: conic-gradient(from 140deg, var(--primary), var(--accent), var(--secondary), var(--primary)); box-shadow: 0 0 26px rgba(var(--primary-rgb, 179,20,50), .45); }
.atelier-dash .b-avatar span { width: 80px; height: 80px; border-radius: 50%; background: #160a0e; display: grid; place-items: center; font-family: var(--cb-serif); font-size: 32px; color: var(--accent); }
.atelier-dash .b-online { display: inline-flex; align-items: center; gap: 7px; font-family: var(--cb-sans); font-size: 11px; letter-spacing: .1em; color: #37d67a; }
.atelier-dash .b-online i { width: 8px; height: 8px; border-radius: 50%; background: #37d67a; }
.atelier-dash .b-name { font-family: var(--cb-serif); font-weight: 600; font-size: clamp(30px, 3.4vw, 48px); line-height: .96; margin: 18px 0 8px; letter-spacing: -.015em; color: #f4eef0; }
.atelier-dash .b-tagline { font-family: var(--cb-serif); font-style: italic; font-size: 17px; color: rgba(244,238,240,.82); margin: 0 0 14px; max-width: 34ch; }
.atelier-dash .b-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.atelier-dash .b-chip { font-family: var(--cb-sans); font-size: 11px; letter-spacing: .05em; color: #f4eef0; border: 1px solid var(--cb-hair); border-radius: 999px; padding: 5px 11px; background: rgba(var(--accent-rgb, 212,175,55), .05); }
.atelier-dash .b-rule { height: 1px; background: linear-gradient(90deg, var(--cb-hair), transparent); margin: 16px 0; }
.atelier-dash .b-cover .b-acts { display: flex; gap: 12px; flex-wrap: wrap; }
/* small-to-medium buttons (were bare links) — hairline theme frame,
 * tracked editorial label, gentle lift on hover */
.atelier-dash .b-cover .b-acts a {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 9px 18px;
    border: 1px solid rgba(var(--accent-rgb, 212, 175, 55), .45);
    border-radius: 11px;
    background: rgba(var(--accent-rgb, 212, 175, 55), .08);
    font-family: var(--cb-sans);
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--accent);
    text-decoration: none;
    transition: background .22s, border-color .22s, transform .22s;
}
.atelier-dash .b-cover .b-acts a:hover {
    text-decoration: none;
    background: rgba(var(--accent-rgb, 212, 175, 55), .18);
    border-color: rgba(var(--accent-rgb, 212, 175, 55), .75);
    transform: translateY(-2px);
}

.atelier-dash .b-metric { display: flex; flex-direction: column; justify-content: space-between; min-height: 150px; }
.atelier-dash .b-metric .b-num { font-size: clamp(36px, 4vw, 50px); display: block; margin: 12px 0 2px; }
.atelier-dash .b-metric .b-d { font-family: var(--cb-sans); font-size: 12px; color: rgba(244,238,240,.5); letter-spacing: .04em; }
.atelier-dash .b-views { grid-area: views; } .atelier-dash .b-admirers { grid-area: admirers; }

.atelier-dash .b-earn { grid-area: earn; display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; flex-wrap: wrap; }
.atelier-dash .b-earn .b-num { font-size: clamp(32px, 3.4vw, 44px); display: block; margin-top: 10px; color: var(--accent); }
.atelier-dash .b-mini { display: flex; gap: 26px; }
.atelier-dash .b-mini .b-num { font-size: 22px; display: block; margin-top: 4px; }

.atelier-dash .b-pulse { grid-area: pulse; min-height: 220px; }
.atelier-dash .b-feed { margin-top: 6px; display: flex; flex-direction: column; }
.atelier-dash .b-ev { display: grid; grid-template-columns: auto 1fr auto; gap: 12px; align-items: center; padding: 11px 0; border-bottom: 1px solid rgba(255,255,255,.06); text-decoration: none; color: inherit; }
.atelier-dash .b-ev:last-child { border-bottom: 0; }
.atelier-dash .b-ev .b-ic { width: 32px; height: 32px; border-radius: 10px; display: grid; place-items: center; color: var(--accent); background: rgba(var(--accent-rgb, 212,175,55), .08); border: 1px solid var(--cb-hair); }
.atelier-dash .b-ev .b-t { font-family: var(--cb-sans); font-size: 13.5px; color: #f4eef0; } .atelier-dash .b-ev .b-t small { display: block; color: rgba(244,238,240,.52); font-size: 11px; margin-top: 1px; }
.atelier-dash .b-ev .b-n { font-family: var(--cb-serif); color: var(--accent); font-size: 16px; }

.atelier-dash .b-film { grid-area: film; }
.atelier-dash .b-film .b-fh { display: flex; justify-content: space-between; align-items: center; margin-bottom: 14px; }
.atelier-dash .b-film .b-fh a { color: var(--accent); text-decoration: none; }
.atelier-dash .b-strip { display: flex; gap: 12px; }
.atelier-dash .b-frame { flex: 1; aspect-ratio: 3/4; border-radius: 12px; position: relative; overflow: hidden; border: 1px solid var(--cb-hair); transition: transform .35s cubic-bezier(.2,.7,.2,1); }
.atelier-dash .b-frame:nth-child(odd) { transform: rotate(-1.2deg); } .atelier-dash .b-frame:nth-child(even) { transform: rotate(1deg) translateY(5px); }
.atelier-dash .b-frame:hover { transform: rotate(0) translateY(-6px) scale(1.03); z-index: 2; }
.atelier-dash .b-frame i { position: absolute; inset: 0; background: radial-gradient(120% 80% at 30% 12%, rgba(var(--accent-rgb, 212,175,55), .34), transparent 58%), linear-gradient(155deg, rgba(var(--primary-rgb, 179,20,50), .55), rgba(var(--secondary-rgb, 122,14,34), .9)); }
.atelier-dash .b-frame b { position: absolute; left: 8px; bottom: 8px; font-family: var(--cb-sans); font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase; background: rgba(0,0,0,.35); padding: 3px 6px; border-radius: 6px; color: #fff; }

.atelier-dash .b-admin { grid-area: admin; }
.atelier-dash .b-adgrid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; margin-top: 12px; }
.atelier-dash .b-adlink { display: flex; align-items: center; gap: 10px; border: 1px solid var(--cb-hair); border-radius: 12px; background: rgba(0,0,0,.18); padding: 11px 13px; cursor: pointer; text-decoration: none; color: #f4eef0; font-family: var(--cb-sans); font-size: 13px; transition: background .25s; text-align: left; }
.atelier-dash .b-adlink:hover { background: rgba(var(--accent-rgb, 212,175,55), .12); }

.atelier-dash .b-dock { grid-area: dock; display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
.atelier-dash .b-act { display: flex; align-items: center; gap: 14px; border: 1px solid var(--cb-hair); border-radius: 14px; background: rgba(255,255,255,.028); padding: 16px 18px; cursor: pointer; text-decoration: none; color: #f4eef0; transition: transform .3s cubic-bezier(.2,.7,.2,1), border-color .3s, background .3s; text-align: left; }
.atelier-dash .b-act:hover { transform: translateY(-3px); border-color: rgba(var(--accent-rgb, 212,175,55), .5); background: rgba(255,255,255,.05); }
.atelier-dash .b-act .b-ic { width: 38px; height: 38px; border-radius: 11px; display: grid; place-items: center; color: var(--accent); background: rgba(var(--accent-rgb, 212,175,55), .09); border: 1px solid var(--cb-hair); flex: 0 0 auto; }
.atelier-dash .b-act .b-lab { font-family: var(--cb-serif); font-size: 17px; } .atelier-dash .b-act .b-sub { font-size: 11px; color: rgba(244,238,240,.52); }

@media (max-width: 900px) {
    .atelier-dash .bento, .atelier-dash.has-admin .bento { grid-template-columns: 1fr 1fr; grid-template-areas: 'cover cover' 'views admirers' 'earn earn' 'pulse pulse' 'film film' 'admin admin' 'dock dock'; }
    .atelier-dash .b-dock, .atelier-dash .b-adgrid { grid-template-columns: 1fr 1fr; }
    .atelier-dash .b-name { font-size: clamp(28px, 8vw, 44px); }}
/* phone tier: two 166px columns clip the 36px+ metric numbers (the cells
   are overflow:hidden, so digits were silently truncated) — stack to one
   column and let the numbers scale with the viewport */
@media (max-width: 480px) {
    .atelier-dash .bento, .atelier-dash.has-admin .bento {
        grid-template-columns: 1fr;
        grid-template-areas: 'cover' 'views' 'admirers' 'earn' 'pulse' 'film' 'admin' 'dock';
    }
    .atelier-dash .b-metric .b-num { font-size: clamp(26px, 10vw, 50px); }
}

/* ========================= HALO (reserved) ========================== */
/* data-design="halo" — selectable now, no visual change yet. */

/* ========================= KINETIK (reserved) ====================== */
/* data-design="kinetik" — selectable now, no visual change yet. */

/* reduced motion: nothing here animates, so nothing to gate. */

/* ---- Modal scrollbars (every page, every design) -------------------- *
 * The modal body is the scroll container; style its bar thin and themed
 * and keep it clear of the rounded corners so it never looks like it
 * sits outside the pop-up. */
.modal-content,
.modal-content .kt-form,
.modal-content #ktLogBody { scrollbar-width: thin; scrollbar-color: rgba(var(--primary-rgb, 179,20,50), .5) transparent; }
.modal-content::-webkit-scrollbar,
.modal-content .kt-form::-webkit-scrollbar,
.modal-content #ktLogBody::-webkit-scrollbar { width: 8px; }
.modal-content::-webkit-scrollbar-track,
.modal-content .kt-form::-webkit-scrollbar-track,
.modal-content #ktLogBody::-webkit-scrollbar-track { background: transparent; margin: 24px 0; }
.modal-content::-webkit-scrollbar-thumb,
.modal-content .kt-form::-webkit-scrollbar-thumb,
.modal-content #ktLogBody::-webkit-scrollbar-thumb { background: rgba(var(--primary-rgb, 179,20,50), .45); border-radius: 8px; }
.modal-content::-webkit-scrollbar-thumb:hover,
.modal-content .kt-form::-webkit-scrollbar-thumb:hover,
.modal-content #ktLogBody::-webkit-scrollbar-thumb:hover { background: rgba(var(--primary-rgb, 179,20,50), .7); }

/* ---- Background scroll-lock while a pop-up is open ------------------ *
 * With a modal open, the page behind kept its own scrollbar at the
 * viewport edge — over the darkened overlay it reads as the pop-up's
 * scrollbar sitting OUTSIDE the box. Lock the page whenever any overlay
 * is shown; the pop-up keeps its own (themed, inside-the-border) bar. */
html:has(:is(.modal, .modal-overlay, .confirm-modal-overlay,
             .logout-modal-overlay, .compliance-modal-overlay,
             .logo-confirm-overlay, .profile-popup-overlay,
             .kt-confirm-overlay).show),
html:has(.login-modal:not(.hidden)),
html:has(.preview-modal:not(.hidden)) {
    overflow: hidden;
}

/* ---- Modal scroll containment (pairs with theme.js containModalScroll) *
 * The pop-up box never scrolls; the wrapped body area does — so the
 * title + close button stay visible and the scrollbar sits INSIDE the
 * frame with breathing room. */
.modal-content:has(> .modal-body-scroll) {
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
.modal-content > .modal-body-scroll {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    margin-right: -24px;   /* bar sits ~16px inside the box edge */
    padding-right: 16px;
    padding-bottom: 6px;   /* keep bottom borders (e.g. action buttons) unclipped */
}
.modal-content > .modal-body-scroll {
    scrollbar-width: thin;
    scrollbar-color: rgba(var(--primary-rgb, 179,20,50), .5) transparent;
}
.modal-content > .modal-body-scroll::-webkit-scrollbar { width: 8px; }
.modal-content > .modal-body-scroll::-webkit-scrollbar-track { background: transparent; margin: 8px 0; }
.modal-content > .modal-body-scroll::-webkit-scrollbar-thumb {
    background: rgba(var(--primary-rgb, 179,20,50), .45);
    border-radius: 8px;
}
.modal-content > .modal-body-scroll::-webkit-scrollbar-thumb:hover {
    background: rgba(var(--primary-rgb, 179,20,50), .7);
}

/* ---- Alerts always on top ------------------------------------------ *
 * The alert pop-up shares .modal's z-index with every other pop-up, so
 * an error raised while another window is open (e.g. a failed save from
 * inside Website Theme) rendered UNDERNEATH it — invisible. Alerts are
 * feedback; they outrank whatever raised them. */
.modal.alert-modal { z-index: 10005; }

/* ---- Your Profile cover: clock (in the avatar slot) + date line ---- */
.atelier-dash .b-cover { position: relative; }
.atelier-dash .b-cover .b-avatar-clock {
    flex: 0 0 auto;
    width: 100px;
    pointer-events: none;
}
.atelier-dash .b-cover .b-cover-date {
    margin-top: 7px;
    font-family: var(--cb-sans);
    font-size: 11px;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: rgba(var(--accent-rgb, 212, 175, 55), .85);
}
@media (max-width: 700px) {
    .atelier-dash .b-cover .b-cover-clock { width: 92px; top: 14px; right: 14px; }}

/* =====================================================================
 *  Shared header user cluster (avatar + name + status + badge + dropdown)
 *  Paired with header-user.js. Colour-carrying badge/status rules are
 *  scoped under the cluster so they never collide with the badge chips
 *  used in members/admin tables. Dashboards keep their own inline copy.
 * ===================================================================== */
.header-right { display: flex; align-items: center; gap: 18px; }
.header-home-link {
    color: #ccc; text-decoration: none; font-weight: 500; white-space: nowrap;
    transition: color 0.3s;
}
.header-home-link:hover { color: var(--primary); }
.user-avatar-section { position: relative; }
.user-avatar-trigger {
    display: flex; align-items: center; gap: 12px; cursor: pointer;
    padding: 8px 15px; border-radius: 25px; transition: background 0.3s;
}
.user-avatar-trigger:hover { background: rgba(var(--primary-rgb), 0.1); }
.user-avatar-section .header-avatar {
    width: 40px; height: 40px; border-radius: 50%;
    background: var(--gradient-hl, var(--gradient)); background-size: 200% 200%;
    display: flex; align-items: center; justify-content: center;
    font-size: 20px; color: #fff; overflow: hidden; flex: 0 0 auto;
    box-shadow: 0 0 18px rgba(var(--primary-rgb), 0.4);
    transition: transform 0.3s, box-shadow 0.3s;
}
.user-avatar-section .header-avatar:hover { transform: scale(1.06); }
.user-avatar-section .header-avatar img { width: 100%; height: 100%; object-fit: cover; }
.user-avatar-section .user-info { display: flex; flex-direction: column; }
.user-avatar-section .user-name { color: #fff; font-weight: 600; font-size: 14px; }
.user-avatar-section .user-status-line {
    color: #999; font-size: 11px; display: flex; align-items: center; gap: 5px;
}
.user-avatar-section .status-indicator { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; }
.user-avatar-section .status-online  { background: #4caf50; }
.user-avatar-section .status-away    { background: #ff9800; }
.user-avatar-section .status-dnd     { background: #f44336; }
.user-avatar-section .status-offline { background: #757575; }
.user-avatar-section .account-type-badge {
    font-size: 10px; padding: 2px 6px; border-radius: 4px; font-weight: 600; margin-left: 5px; color: #fff;
}
.user-avatar-section .account-type-badge.badge-admin   { background: var(--primary); }
.user-avatar-section .account-type-badge.badge-model   { background: #ff9800; }
.user-avatar-section .account-type-badge.badge-premium { background: var(--secondary); }
.user-avatar-section .account-type-badge.badge-user    { background: #ff9800; }
.user-guest-login {
    color: var(--primary); text-decoration: none; font-weight: 600; font-size: 14px;
    padding: 8px 18px; border: 1px solid rgba(var(--primary-rgb), 0.5); border-radius: 22px;
}
.user-guest-login:hover { background: rgba(var(--primary-rgb), 0.12); }
.avatar-dropdown {
    position: absolute; top: 60px; right: 0; background: #1a1a1a;
    border: 2px solid #2d2d2d; border-radius: 12px; min-width: 220px;
    width: max-content; max-width: calc(100vw - 24px);
    box-shadow: 0 10px 40px rgba(0,0,0,0.5); display: none; z-index: 1100;
}
.avatar-dropdown.show { display: block; }
.avatar-dropdown .dropdown-section { padding: 15px; border-bottom: 1px solid #2d2d2d; }
.avatar-dropdown .dropdown-section:last-child { border-bottom: none; }
.avatar-dropdown .dropdown-header {
    color: #999; font-size: 11px; text-transform: uppercase; margin-bottom: 10px; font-weight: 600;
}
.avatar-dropdown .status-option {
    display: flex; align-items: center; gap: 10px; padding: 8px 12px;
    cursor: pointer; border-radius: 8px; color: #ccc;
}
.avatar-dropdown .status-option:hover,
.avatar-dropdown .status-option.active { background: rgba(var(--primary-rgb), 0.1); color: var(--primary); }
.avatar-dropdown .status-indicator { width: 10px; height: 10px; border-radius: 50%; }
.avatar-dropdown .status-online  { background: #4caf50; }
.avatar-dropdown .status-away    { background: #ff9800; }
.avatar-dropdown .status-dnd     { background: #f44336; }
.avatar-dropdown .status-offline { background: #757575; }
.avatar-dropdown .dropdown-link {
    display: flex; align-items: center; white-space: nowrap; padding: 10px 12px; color: #ccc; text-decoration: none; border-radius: 8px;
}
.avatar-dropdown .dropdown-link:hover { background: rgba(var(--primary-rgb), 0.1); color: var(--primary); }

/* ---- Member-page header: ONE uniform, right-justified layout -------- *
 * logo (far left) | ....gap.... | notif icons + nav links + cluster (right).
 * Everything after the logo is pushed right via margin-left:auto on the
 * first item. These rules are deliberately specific so they win over each
 * page's older inline header CSS and render every member page identically. */
nav.hdr-member { justify-content: flex-start; gap: 16px; flex-wrap: wrap; }
nav.hdr-member .notif-icons { margin-left: auto; display: flex; align-items: center; gap: 6px; }
nav.hdr-member .header-nav-links { margin: 0; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
nav.hdr-member .header-right { margin: 0; display: flex; align-items: center; gap: 14px; }

/* Guest state — .notif-icons is hidden (auth-only) and it is the element
   carrying margin-left:auto, so without this the links + chip + buttons
   would collapse back against the logo. header-user.js sets .is-guest on
   <html>, and the nav links take over the auto margin, keeping the guest
   header right-justified exactly like the signed-in one. */
html.is-guest nav.hdr-member .header-nav-links { margin-left: auto; }

/* notification buttons — identical size + style regardless of nesting */
nav.hdr-member .notif-btn {
    position: relative; display: flex; align-items: center; justify-content: center;
    width: 40px; height: 40px; padding: 0; border-radius: 10px;
    background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.08);
    color: #ccc; text-decoration: none; transition: background .2s, border-color .2s, color .2s;
}
nav.hdr-member .notif-btn:hover {
    background: rgba(var(--primary-rgb), 0.14); color: #fff; border-color: var(--primary);
}
nav.hdr-member .notif-btn svg { width: 20px; height: 20px; }
nav.hdr-member .notif-badge {
    position: absolute; top: -6px; right: -6px; min-width: 18px; height: 18px;
    padding: 0 5px; border-radius: 9px; background: var(--primary); color: #fff;
    font-size: 11px; font-weight: 700; align-items: center; justify-content: center;
    line-height: 1;
    display: none;   /* hidden until notifications.js reveals a real count > 0 */
}

/* Header notification icons on pages that DON'T use nav.hdr-member — the
 * public info pages (About, Contact, …) and the admin tool pages. Same look as
 * the member header so the cluster is identical everywhere. Guest-gating is
 * done per public page with html.is-authed (matching their avatar gating);
 * admin pages are admin-only, so the cluster there is always for an admin. */
/* scoped as .notif-icons .notif-btn (two classes) so the cluster keeps its
 * icon-button look even when it sits INSIDE a nav-links row whose `a` styling
 * would otherwise win. */
.notif-icons { display: flex; align-items: center; gap: 6px; }
.notif-icons .notif-btn {
    position: relative; display: flex; align-items: center; justify-content: center;
    width: 40px; height: 40px; padding: 0; border-radius: 10px;
    background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.08);
    color: #ccc; text-decoration: none; transition: background .2s, border-color .2s, color .2s;
}
.notif-icons .notif-btn:hover { background: rgba(var(--primary-rgb), 0.14); color: #fff; border-color: var(--primary); }
.notif-icons .notif-btn svg { width: 20px; height: 20px; }
.notif-icons .notif-badge {
    position: absolute; top: -6px; right: -6px; min-width: 18px; height: 18px;
    padding: 0 5px; border-radius: 9px; background: var(--primary); color: #fff;
    font-size: 11px; font-weight: 700; align-items: center; justify-content: center;
    line-height: 1; display: none;
}

/* ── Nav count badges (.cb-navcount) ───────────────────────────────────
 *  The number on the right of Friends / Members / Mailbox / Messages &
 *  Chat — friends and members ONLINE, mail and messages UNREAD. Painted
 *  by notifications.js onto any nav link pointing at those pages, so the
 *  Draconium rail and the header nav (which the Sidebar Panel layout
 *  turns into a rail) get the same treatment from one rule.
 *
 *  Deliberately NOT the absolutely-positioned .notif-badge look above:
 *  that one is a corner dot on a 40px icon button, whereas this sits in
 *  the flow at the end of a full-width row. `hidden` does the hiding, so
 *  there is no display:none here to fight with. */
.cb-navcount {
    display: inline-flex; align-items: center; justify-content: center;
    min-width: 16px; height: 15px; padding: 0 4px; margin-left: 8px;
    border-radius: 999px; background: var(--primary, #C40E2E); color: #fff;
    font-size: 9.5px; font-weight: 700; line-height: 1; letter-spacing: .01em;
    flex: 0 0 auto;   /* a flex item shrinks below its width by default,
                         which would squash the pill on a narrow rail */
}
.cb-navcount[hidden] { display: none; }
/* On the Draconium rail the row is already flex, so auto-margin parks the
 * pill hard right — "on the right side of the buttons", as asked. */
.dr-snav .cb-navcount { margin-left: auto; }
/* The row is `white-space:nowrap`, so a long label cannot wrap and, having
 * no min-width:0, refuses to shrink either — it shoves the pill out past
 * the rail's edge. Rail labels are ADMIN-EDITABLE (Website Layout ›
 * Sidebar), so "Messages & Chat" can become anything. Let the label
 * ellipsise instead. Scoped with :has() to rows that actually carry a
 * pill, so every other rail button keeps its existing behaviour. */
.dr-snav:has(.cb-navcount) .t {
    min-width: 0; overflow: hidden; text-overflow: ellipsis;
}
/* The Sidebar Panel layout's links are display:block, so there is nothing
 * for an auto margin to push against. Promote ONLY the badged ones to
 * flex — :has() keeps every other nav link exactly as it was, and where
 * :has() is unsupported the pill simply sits inline after the label,
 * which still reads correctly. */
html[data-dashboard="sidebar"] .navbar .nav-links a:has(.cb-navcount),
html[data-dashboard="sidebar"] > body > header .nav-links > a:has(.cb-navcount),
html[data-dashboard="sidebar"] > body > header .header-nav-links > a:has(.cb-navcount) {
    display: flex; align-items: center;
}
html[data-dashboard="sidebar"] .nav-links a .cb-navcount,
html[data-dashboard="sidebar"] .header-nav-links > a .cb-navcount { margin-left: auto; }
/* A selected row uses the gradient fill, where a primary-coloured pill on
 * a primary-coloured background would vanish. */
.dr-snav[aria-current="page"] .cb-navcount,
.nav-links > a.active .cb-navcount,
.header-nav-links > a.active .cb-navcount {
    background: rgba(0, 0, 0, .38); color: #fff;
}

/* nav links — one uniform look, filled-pill active state on every page */
nav.hdr-member .header-nav-links a {
    color: #ccc; text-decoration: none; padding: 8px 16px; border-radius: 8px;
    font-size: 14px; font-weight: 500; transition: background .2s, color .2s; white-space: nowrap;
}
nav.hdr-member .header-nav-links a:hover { background: rgba(var(--primary-rgb), 0.12); color: #fff; }
nav.hdr-member .header-nav-links a.active { background: var(--gradient-active, var(--gradient)); color: #fff; }

/* ---- Admin content-page header: right-justified nav (matches the rest) */
nav.hdr-admin { justify-content: flex-start; gap: 16px; flex-wrap: wrap; }
nav.hdr-admin .nav-links { margin-left: auto; }
nav.hdr-admin .header-right { margin: 0; }
/* dropdown menu item icons */
/* Dropdown icons are icons.css masks (.ic), not emoji — width/height are
   fixed here so every row's label starts on the same x, whatever the
   design language's icon set does. */
.avatar-dropdown .dd-ic {
    display: inline-block;
    width: 16px; height: 16px;
    margin-right: 10px;
    vertical-align: -0.18em;
    flex: none;
}

/* Guest chip (Home): no account actions to show, so the dropdown stays
 * shut — otherwise toggling it renders an empty bordered strip. */
.avatar-dropdown.dd-guest { display: none !important; }
.user-avatar-section.is-guest-chip .user-avatar-trigger { cursor: default; }
.user-avatar-section.is-guest-chip .user-avatar-trigger:hover { background: transparent; }

/* Guest header buttons on member pages — same look as Home. Hidden for
 * signed-in visitors by header-user.js. */
nav.hdr-member .create-account-btn {
    background: transparent; color: var(--primary);
    border: 2px solid var(--primary);
    padding: 7px 20px; border-radius: 25px;
    font-weight: 600; font-size: 14px; text-decoration: none; white-space: nowrap;
    transition: background .25s, color .25s, transform .25s;
}
nav.hdr-member .create-account-btn:hover {
    background: rgba(var(--primary-rgb), 0.12); color: #fff; transform: scale(1.04);
}
nav.hdr-member .login-btn {
    background: var(--gradient); color: #fff;
    padding: 9px 24px; border-radius: 25px;
    font-weight: 600; font-size: 14px; text-decoration: none; white-space: nowrap;
    box-shadow: 0 4px 15px rgba(var(--primary-rgb), 0.3);
    transition: transform .25s, box-shadow .25s;
}
nav.hdr-member .login-btn:hover {
    transform: scale(1.04); box-shadow: 0 6px 22px rgba(var(--primary-rgb), 0.5);
}

/* @property (above) is what lets the browser interpolate the angle. It is
   supported in every current browser; where it is not, the custom property
   can't be interpolated and the sweep degrades to a discrete step rather
   than smooth motion. That is acceptable, and there is no honest feature
   test for it worth adding here — an earlier attempt tested for Houdini
   paint worklets, which has nothing to do with @property. */

/* =====================================================================
 *  SEGMENTED SWITCH  —  .cb-switch
 *
 *  A two-segment control: the track holds both states as words, and a
 *  pill slides to the one that's active. You read the state, you don't
 *  infer it from a dot's position — which matters here, because every
 *  toggle on this site is an ADMIN control deciding whether something is
 *  live on the site (Maintenance Mode, an archetype, the ambient effects).
 *
 *  Markup is UNCHANGED, so no page's HTML moved:
 *      <label class="cb-switch"><input type="checkbox"><span class="cb-slider"></span></label>
 *      .cb-switch          the track
 *      .cb-switch::before  the word "Off"   (left segment)
 *      .cb-switch::after   the word "On"    (right segment)
 *      .cb-slider          the pill that slides under the active word
 *
 *  The words are drawn by the label's own pseudo-elements and the pill is
 *  the span, so the two sit in separate layers — z-index keeps the words
 *  above the pill regardless of DOM order.
 *
 *  Off is a neutral pill; On takes the theme. So the colour means "live",
 *  and one component serves all 21 palettes with no per-theme overrides.
 * ===================================================================== */

.cb-switch {
    position: relative;
    display: inline-block;
    width: 74px;
    height: 28px;
    flex: 0 0 auto;
    cursor: pointer;
    border-radius: 999px;
    background: rgba(255, 255, 255, .05);
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .12);
    -webkit-user-select: none;
            user-select: none;
    transition: box-shadow .18s ease;
}
.cb-switch:hover { box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .22); }
.cb-switch input { position: absolute; opacity: 0; width: 0; height: 0; }

/* The sliding pill. Sits UNDER the words. */
.cb-switch .cb-slider {
    position: absolute;
    z-index: 1;
    top: 3px;
    left: 3px;
    width: calc(50% - 4px);
    height: calc(100% - 6px);
    border-radius: 999px;
    background: #d9d9e2;
    box-shadow: 0 1px 3px rgba(0, 0, 0, .45);
    /* A short, firm move — this is a control, not a toy. */
    transition: transform .2s cubic-bezier(.3, 1.4, .4, 1), background .2s ease;
}

/* The two words. Above the pill. */
.cb-switch::before,
.cb-switch::after {
    position: absolute;
    z-index: 2;
    top: 0;
    height: 100%;
    width: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: inherit;
    font-size: 10px;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    pointer-events: none;
    transition: color .2s ease;
}
.cb-switch::before { content: "Off"; left: 0;  color: #15151b; }   /* on the pill */
.cb-switch::after  { content: "On";  right: 0; color: rgba(255,255,255,.5); }

/* ── Thrown ───────────────────────────────────────────────────────── */
.cb-switch input:checked ~ .cb-slider {
    transform: translateX(calc(100% + 2px));
    background: var(--primary, #e91e63);
    box-shadow: 0 1px 3px rgba(0,0,0,.45),
                0 0 10px -1px rgba(var(--primary-rgb, 233,30,99), .7);
}
.cb-switch:has(input:checked)::before { color: rgba(255,255,255,.5); }
.cb-switch:has(input:checked)::after  { color: #fff; }

/* Keyboard focus has to be visible on a control this small. */
.cb-switch input:focus-visible ~ .cb-slider {
    outline: 2px solid var(--primary, #e91e63);
    outline-offset: 2px;
}

/* ── Small (used in dense rows: ambient kinds, question source) ────── */
.cb-switch.cb-switch-sm { width: 62px; height: 22px; }
.cb-switch.cb-switch-sm .cb-slider {
    top: 2.5px; left: 2.5px;
    width: calc(50% - 3.5px);
    height: calc(100% - 5px);
}
.cb-switch.cb-switch-sm::before,
.cb-switch.cb-switch-sm::after { font-size: 9px; letter-spacing: .07em; }
.cb-switch.cb-switch-sm input:checked ~ .cb-slider {
    transform: translateX(calc(100% + 1px));
}

/* ── Reduced motion: the state still changes, the pill just doesn't slide. */
@media (prefers-reduced-motion: reduce) {
    .cb-switch,
    .cb-switch .cb-slider,
    .cb-switch::before,
    .cb-switch::after {
        transition: none;
    }}

/* ── :has() fallback ───────────────────────────────────────────────
   The word colours swap via .cb-switch:has(input:checked), because the
   words live on the LABEL and the state lives on the input inside it —
   there is no sibling selector that reaches a parent. :has() is in every
   current browser, but if it's missing the words would otherwise be left
   dark-on-dark when thrown. Give both a mid-tone that stays legible on
   the pill AND on the track, so the control degrades to merely less
   emphatic rather than unreadable. */
@supports not selector(:has(*)) {
    .cb-switch::before,
    .cb-switch::after { color: #6f7480; }}

/* ══════════════════════════════════════════════════════════════════════════
 *  Container fill toggle — SITE-WIDE (beyond the dashboard layouts).
 *
 *  The admin "Container fill: Solid" setting (Website Theme → Dashboard Layout)
 *  puts html[data-dash-containers="solid"] on <html> via theme.js on EVERY
 *  page. Dashboard layouts flip their own shared tokens (--cd-pnl / --dr-*);
 *  the content pages below each style their containers with bespoke translucent
 *  fills, so here we flip their MAIN structural panels/cards to one opaque,
 *  theme-aware fill (the same subtle tint mixed over the theme's --cb-ink).
 *
 *  Scope is deliberate: ONLY flat-fill structural containers are listed.
 *  Decorative GRADIENT panels (.cta-strip, .story-visual, .office-card,
 *  .subscribe-inner, .agent-card-inner, .kt-confirm-box) and small semantic
 *  accent boxes (.disclaimer, .form-success, .selling-note, badges, chips)
 *  are intentionally left alone. Transparent (default) mode is 100% untouched —
 *  these rules exist ONLY under the [data-dash-containers="solid"] attribute.
 *  A new container just needs to be added to this :is() list to be covered. */
html[data-dash-containers="solid"] :is(
    /* shared public template — about, contact, faq, content-removal, dmca, terms, privacy */
    .stat-card, .value-card, .form-card, .info-card, .method-card, .rail-card,
    .process-step, .legal-doc, .legal-toc, .faq-item,
    /* events / pricing */
    .event-card, .plan, .calc-card,
    /* members / friends / media / shop */
    .member-card, .request-card, .media-card, .sidebar,
    /* kink test + result */
    .stage, .results-grid, .privacy-panel, .share-box,
    /* messages & chat */
    .chat, .mc-chat, .mc-tabs, .mc-roster, .thread-list,
    /* bio / profile / auth (login, register) */
    .bio-card, .bio-hero, .bio-view-panel, .view-detail, .view-kink-card, .zodiac-card,
    .login-container, .register-container, .confirm-summary, .profile-container,
    /* admin dashboard + tool pages (non-Draconium layouts) */
    .section, .upload-area, .upload-card, .controls-bar, .ss-card, .selling-summary,
    .content-item, .content-controls, .portfolio-item, .users-table-container,
    .an-section, .an-chart-wrap, .an-listing-tile, .an-range-group,
    .kt-panel-cell, .kt-weight-grid, .kt-io-log,
    .logo-card, .logo-upload-area, .maint-preview,
    /* shared media */
    .radio-card, .ss-stat, .sell-detail, .inline-note,
    /* mail / mailbox / admin inbox / activity log / admin roster */
    .ib-row, .ac-stat, .rt2-card, .asg-card,
    /* kink test result — Compatibility scan rows */
    .ktc-row
) {
    background: color-mix(in srgb, var(--cb-text, #fff) 4%, var(--cb-ink, #0e0f16)) !important;
    -webkit-backdrop-filter: none !important;
            backdrop-filter: none !important;
}

/* =====================================================================
 *  THEMED CONFIRM DIALOG — shared (2026-07-25)
 *  The site's pop-up replacement for native confirm()/alert(): the same
 *  dialog the admin pages carry inline, centralised so EVERY page can use
 *  it by adding the markup + helper only (standing rule: never use a
 *  native browser pop-up). Pages that still define these classes inline
 *  simply override this copy — the values are identical.
 *  Keyframes are cbcm-prefixed so they can't collide with page-level ones.
 * ===================================================================== */
@keyframes cbcm-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes cbcm-drop { from { opacity: 0; transform: translateY(-26px); } to { opacity: 1; transform: translateY(0); } }
@keyframes cbcm-glow {
    0%, 100% { box-shadow: 0 8px 24px rgba(var(--primary-rgb, 179,20,50), 0.35); }
    50%      { box-shadow: 0 8px 32px rgba(var(--primary-rgb, 179,20,50), 0.55); }
}
.confirm-modal-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.7);
    backdrop-filter: blur(10px);
    z-index: 10001;
    animation: cbcm-fade 0.25s ease;
}
.confirm-modal-overlay.show {
    display: flex;
    justify-content: center;
    align-items: center;
}
.confirm-modal {
    background: rgba(26, 26, 26, 0.96);
    backdrop-filter: blur(20px);
    border-radius: 20px;
    padding: 36px 36px 28px;
    min-width: 360px;
    max-width: 480px;
    width: calc(100% - 40px);
    border: 2px solid rgba(var(--primary-rgb), 0.3);
    box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5),
                0 0 40px rgba(var(--primary-rgb), 0.2),
                inset 0 0 30px rgba(255, 255, 255, 0.05);
    animation: cbcm-drop 0.3s ease;
    position: relative;
    overflow: hidden;
    box-sizing: border-box;
}
.confirm-modal::before {
    content: '';
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 4px;
    background: var(--gradient-hl, var(--gradient));
}
.confirm-modal.variant-danger::before  { background: linear-gradient(90deg, #ff7043 0%, #d84315 100%); }
.confirm-modal.variant-warning::before { background: linear-gradient(90deg, #ffa726 0%, #ef6c00 100%); }
.confirm-modal.variant-success::before { background: linear-gradient(90deg, #66bb6a 0%, #2e7d32 100%); }
.confirm-modal-icon {
    width: 78px;
    height: 78px;
    margin: 0 auto 18px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 38px;
    background: var(--gradient-hl, var(--gradient));
    box-shadow: 0 8px 24px rgba(var(--primary-rgb), 0.35);
    animation: cbcm-glow 2s ease-in-out infinite;
}
.confirm-modal.variant-danger  .confirm-modal-icon {
    background: linear-gradient(135deg, #ff7043 0%, #d84315 100%);
    box-shadow: 0 8px 24px rgba(216, 67, 21, 0.45);
}
.confirm-modal.variant-warning .confirm-modal-icon {
    background: linear-gradient(135deg, #ffa726 0%, #ef6c00 100%);
    box-shadow: 0 8px 24px rgba(239, 108, 0, 0.45);
}
.confirm-modal.variant-success .confirm-modal-icon {
    background: linear-gradient(135deg, #66bb6a 0%, #2e7d32 100%);
    box-shadow: 0 8px 24px rgba(46, 125, 50, 0.45);
}
.confirm-modal-title {
    font-size: 22px;
    font-weight: 700;
    text-align: center;
    margin-bottom: 12px;
    background: var(--gradient-hl, var(--gradient));
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}
.confirm-modal.variant-danger  .confirm-modal-title { background: linear-gradient(135deg, #ff7043 0%, #d84315 100%); -webkit-background-clip: text; background-clip: text; }
.confirm-modal.variant-warning .confirm-modal-title { background: linear-gradient(135deg, #ffa726 0%, #ef6c00 100%); -webkit-background-clip: text; background-clip: text; }
.confirm-modal.variant-success .confirm-modal-title { background: linear-gradient(135deg, #66bb6a 0%, #2e7d32 100%); -webkit-background-clip: text; background-clip: text; }
.confirm-modal-message {
    color: #cccccc;
    text-align: center;
    font-size: 15px;
    line-height: 1.6;
    margin-bottom: 26px;
    white-space: pre-line;
}
.confirm-modal-buttons {
    display: flex;
    gap: 12px;
    justify-content: center;
    flex-wrap: wrap;
}
.confirm-modal-btn {
    padding: 11px 26px;
    border-radius: 12px;
    font-size: 15px;
    font-weight: 600;
    cursor: pointer;
    border: none;
    transition: all 0.25s ease;
    min-width: 120px;
    font-family: inherit;
}
.confirm-modal-btn-cancel {
    background: rgba(255, 255, 255, 0.05);
    color: #cccccc;
    border: 1px solid rgba(255, 255, 255, 0.1);
}
.confirm-modal-btn-cancel:hover {
    background: rgba(255, 255, 255, 0.1);
    border-color: rgba(255, 255, 255, 0.2);
}
.confirm-modal-btn-confirm {
    background: var(--gradient);
    color: #fff;
    box-shadow: 0 4px 15px rgba(var(--primary-rgb), 0.4);
}
.confirm-modal-btn-confirm:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 20px rgba(var(--primary-rgb), 0.6);
}
.confirm-modal.variant-danger  .confirm-modal-btn-confirm {
    background: linear-gradient(135deg, #ff7043 0%, #d84315 100%);
    box-shadow: 0 4px 15px rgba(216, 67, 21, 0.4);
}
.confirm-modal.variant-danger  .confirm-modal-btn-confirm:hover { box-shadow: 0 6px 22px rgba(216, 67, 21, 0.6); }
.confirm-modal.variant-warning .confirm-modal-btn-confirm {
    background: linear-gradient(135deg, #ffa726 0%, #ef6c00 100%);
    box-shadow: 0 4px 15px rgba(239, 108, 0, 0.4);
}
.confirm-modal.variant-warning .confirm-modal-btn-confirm:hover { box-shadow: 0 6px 22px rgba(239, 108, 0, 0.6); }
.confirm-modal.variant-success .confirm-modal-btn-confirm {
    background: linear-gradient(135deg, #66bb6a 0%, #2e7d32 100%);
    box-shadow: 0 4px 15px rgba(46, 125, 50, 0.4);
}
.confirm-modal.variant-success .confirm-modal-btn-confirm:hover { box-shadow: 0 6px 22px rgba(46, 125, 50, 0.6); }
@media (max-width: 480px) {
    .confirm-modal { padding: 28px 22px 22px; min-width: 0; }
    .confirm-modal-icon { width: 64px; height: 64px; font-size: 32px; }
    .confirm-modal-title { font-size: 19px; }
    .confirm-modal-message { font-size: 14px; }
    .confirm-modal-buttons { gap: 10px; }
    .confirm-modal-btn { flex: 1 1 100%; min-width: 0; }
}

/* =====================================================================
 *  DRACONIUM MINIMAL — content-page density (2026-08-04)
 *
 *  When the Website Layout is Draconium Minimal, the member-facing
 *  pages (Members, Friends, Shop, the three Content Management pages)
 *  drop one size class to match the minimal admin shell: tighter
 *  containers, cards, buttons/tabs, sidebar and search bar. Gated on
 *  the html attribute, so every other layout is 100% untouched.
 *
 *  RESPONSIVE GUARD: anything that changes a column layout or a rail
 *  width lives inside the min-width media query below — the pages' own
 *  phone breakpoints (collapse to one column, drawer sidebar) must keep
 *  winning on small screens, and these attribute-gated selectors would
 *  otherwise outrank them at every width.
 * ===================================================================== */

/* tabs + pills: now fully handled by the UNIFORM TAB SYSTEM section at
   the end of this file (2026-08-04) — one shared recipe for every page. */

/* filter sidebar (Members / Friends / Shop) */
html[data-dashboard="draconium-min"] .sidebar { padding: 16px; border-radius: 14px; }
html[data-dashboard="draconium-min"] .sidebar h3 { font-size: 13.5px; margin-bottom: 12px; }
html[data-dashboard="draconium-min"] .filter-group { margin-bottom: 12px; }
html[data-dashboard="draconium-min"] .filter-group select,
html[data-dashboard="draconium-min"] .filter-group input { padding: 7px 9px; font-size: 12.5px; }
html[data-dashboard="draconium-min"] .clear-filters-btn { padding: 8px; font-size: 12.5px; }

/* search bar — vertical trim + type only; horizontal padding stays as
   authored (Members reserves room for its inline search icon, Shop
   does not, so a shared left padding would misalign one of them). */
html[data-dashboard="draconium-min"] .search-bar input { padding-top: 10px; padding-bottom: 10px; font-size: 13.5px; }

/* member/friend cards */
html[data-dashboard="draconium-min"] .member-grid { grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 14px; }
html[data-dashboard="draconium-min"] .member-photo { height: 180px; }
html[data-dashboard="draconium-min"] .member-body { padding: 12px 13px 13px; }
html[data-dashboard="draconium-min"] .member-actions { gap: 6px; margin-top: 10px; }
html[data-dashboard="draconium-min"] :is(.view-bio-btn, .favorite-btn, .unfriend-btn) { padding: 8px 10px; font-size: 12.5px; }

/* shop cards */
html[data-dashboard="draconium-min"] .media-grid { grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 14px; }
html[data-dashboard="draconium-min"] .media-body { padding: 10px 12px; }
html[data-dashboard="draconium-min"] .btn-buy { padding: 10px; font-size: 13.5px; }

/* content management (admin/user/model contentmanage) */
/* .content-tabs / .content-tab visuals come from the UNIFORM TAB SYSTEM
   section below; only the page-rhythm margin stays here. */
html[data-dashboard="draconium-min"] .content-tabs { margin-bottom: 20px; }
html[data-dashboard="draconium-min"] .content-controls { padding: 16px; gap: 14px; margin-bottom: 20px; border-radius: 16px; }
html[data-dashboard="draconium-min"] .content-controls .btn { padding: 9px 18px; font-size: 13px; }
html[data-dashboard="draconium-min"] .content-item { border-radius: 16px; }
html[data-dashboard="draconium-min"] :is(.content-edit-btn, .content-delete-btn) { font-size: 12.5px; }

/* Desktop-only layout metrics — never fight the phone breakpoints. */
@media (min-width: 901px) {
    /* Members / Friends: filter rail column narrows with the shell. */
    html[data-dashboard="draconium-min"] .layout { grid-template-columns: 240px 1fr; gap: 18px; }
    html[data-dashboard="draconium-min"] .layout.no-sidebar { grid-template-columns: 1fr; }
    /* Shop's rail is width-based rather than a grid column. */
    html[data-dashboard="draconium-min"] .sidebar { width: 240px; }
}

/* =====================================================================
 *  DRACONIUM MINIMAL — UNIFORM TAB SYSTEM (2026-08-04)
 *
 *  One tab language for every page, copied from the Members page (the
 *  reference design the user approved):
 *    MAIN tabs — borderless text buttons sitting on a shared hairline;
 *                the active tab carries a 3px primary underline (the
 *                capsule radius softly curves its ends); counts live in
 *                small primary-tinted pills that read the same whether
 *                their tab is active or not.
 *    SUB tabs  — capsule chips (dark fill, primary hairline border);
 *                the active chip fills with the design language's
 *                gradient, exactly like the Members sub-pills.
 *
 *  CSS-only: every page keeps its own markup, ids and JS handlers. The
 *  attribute gate gives these recipes (0,3,1)+ specificity, which
 *  out-ranks each page's inline class rules. Admin-SHELL pages carry
 *  higher-specificity main.dr-shell-admin rules, so the same recipes
 *  are re-asserted at the end of draconium-admin.css — keep both
 *  sections in sync when editing.
 *
 *  Deliberately NOT restyled: chart legend chips (.an-legend-pill — the
 *  swatch colours are data), palette-editor swatch chips (.pe-chip),
 *  the emoji-picker category strip, .hc-seg micro-switchers (already
 *  minimal-skinned), and events.html's .event-log-pill (a navigation
 *  link, not a filter).
 *
 *  No layout geometry here (no columns / rail widths), so nothing needs
 *  the responsive re-assert treatment described above. `display` is
 *  left alone on purpose: pages show/hide some of these rows with JS or
 *  a .hidden class and must keep control of it.
 * ===================================================================== */

/* ── MAIN tab rows ────────────────────────────────────────────────────
 * .cat-tabs (Members)      .friend-cat-tabs (Friends)  .mc-tabs (Messages)
 * .category-tabs (Mailbox, My Activity + admin pages)  .content-tabs (×3)
 * .kt-tabs (Kink test)     .an-tabs (Analytics)        .set-tabs (Settings)
 * .log-tabs (Events Log)   .section-tabs (Home)        .tabs (Shared Media) */
html[data-dashboard="draconium-min"] :is(.cat-tabs, .friend-cat-tabs, .mc-tabs, .category-tabs, .content-tabs, .kt-tabs, .an-tabs, .set-tabs, .log-tabs, .section-tabs, .tabs) {
    background: none;
    border: none;
    border-bottom: 1px solid rgba(var(--primary-rgb, 196, 14, 46), .18);
    border-radius: 0;
    padding: 0;
    gap: 6px;
    flex-wrap: wrap;
    box-shadow: none;
}
/* The Mailbox and My Activity Log rows had no row styling at all. */
html[data-dashboard="draconium-min"] :is(#mbTabs, #acTabs) { display: flex; flex-wrap: wrap; }
/* Container-fill SOLID repaints its :is() container list with !important —
   and .mc-tabs / .an-range-group sit in that list from the days they WERE
   pill panels. Under solid mode that beat the strip above and Messages'
   tab row came back as an opaque box (user screenshot 2026-08-05, the one
   state the transparent-mode verification could not catch). Re-strip at
   the same weight; the toggle keeps every real panel (.mc-chat,
   .thread-list, .mc-roster …) solid as designed. */
html[data-dashboard="draconium-min"][data-dash-containers="solid"] :is(.mc-tabs, .an-range-group) {
    background: none !important;
}

/* ── MAIN tab: the tab itself ──────────────────────────────────────── */
html[data-dashboard="draconium-min"] :is(.cat-tab, .friend-cat-tab, .mc-tab, .category-tab, .content-tab, .kt-tab, .an-tab, .set-tab, .log-tab, .tabs .tab, .section-tabs .tab-btn) {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    margin: 0;
    padding: 8px 14px;
    background: none;
    border: none;
    border-bottom: 3px solid transparent;
    border-radius: 999px; /* the site-wide capsule contract — curves the underline's ends */
    box-shadow: none;
    backdrop-filter: none;
    transform: none;
    color: #999;
    font-family: inherit;
    font-size: 13.5px;
    font-weight: 600;
    letter-spacing: normal;
    text-transform: none;
    text-decoration: none;
    line-height: 1.4;
    white-space: nowrap;
    cursor: pointer;
    user-select: none;
    transition: color .2s, border-color .2s, background .2s;
}
html[data-dashboard="draconium-min"] :is(.cat-tab, .friend-cat-tab, .mc-tab, .category-tab, .content-tab, .kt-tab, .an-tab, .set-tab, .log-tab, .tabs .tab, .section-tabs .tab-btn):hover {
    color: #fff;
    background: none;
    box-shadow: none;
    transform: none;
}
html[data-dashboard="draconium-min"] :is(.cat-tab, .friend-cat-tab, .mc-tab, .category-tab, .content-tab, .kt-tab, .an-tab, .set-tab, .log-tab, .tabs .tab, .section-tabs .tab-btn):is(.active, .on) {
    color: #fff;
    background: none;
    border-bottom-color: var(--primary, #C40E2E);
    box-shadow: none;
    transform: none;
}
/* The admin pages carry a shared inline `.kt-tab.active { color/border-color:
   var(--accent) !important }` gold-accent block — counter it at the same
   weight (higher specificity among !important rules), min-gated only. */
html[data-dashboard="draconium-min"] .kt-tab.active {
    color: #fff !important;
    border-color: transparent !important;
    border-bottom-color: var(--primary, #C40E2E) !important;
}

/* ── MAIN tab: count / badge pills ─────────────────────────────────── */
html[data-dashboard="draconium-min"] :is(.cat-tab .tab-count, .category-tab .tab-count, .friend-cat-tab .fc-count, .tabs .tab .pill, .mc-tab .mc-dot, .category-tab .ib-pill, .category-tab .ib-badge, .log-tab .log-tab-badge) {
    min-width: 20px;
    height: auto;
    padding: 1px 7px;
    border-radius: 10px;
    background: rgba(var(--primary-rgb, 196, 14, 46), .22);
    color: inherit;
    font-family: inherit;
    font-size: 11px;
    font-weight: 700;
    letter-spacing: normal;
    text-transform: none;
    line-height: 1.5;
    text-align: center;
}
/* …and the pill never changes when its tab activates (pages used to
   swap it to white / gradient / black tints). */
html[data-dashboard="draconium-min"] :is(.cat-tab.active .tab-count, .category-tab.active .tab-count, .friend-cat-tab.active .fc-count, .tabs .tab.active .pill, .mc-tab.on .mc-dot, .log-tab.active .log-tab-badge) {
    background: rgba(var(--primary-rgb, 196, 14, 46), .22);
    color: inherit;
}

/* ── SUB tabs: capsule chips ──────────────────────────────────────────
 * .sub-pill (Members)   .filter-pill (Shop/Media/Shared)  .faq-cat-pill
 * .event-pill (Events)  .sub-tab (Share modal)   .kt-subtab (Kink admin)
 * .mb-segbtn (Mail compose)  .an-range-btn (Analytics date range)
 * .view-mode-btn (Grid/List) .pc-subtab (Theme + Maintenance sub-tabs) */
html[data-dashboard="draconium-min"] :is(.view-mode-toggle, .an-range-group) {
    background: none;
    border: none;
    border-radius: 0;
    padding: 0;
    gap: 8px;
    box-shadow: none;
}
html[data-dashboard="draconium-min"] :is(.sub-pill, .filter-pill, .faq-cat-pill, .event-pill, .sub-tab, .kt-subtab, .mb-segbtn, .an-range-btn, .view-mode-btn, .pc-subtab) {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 12px;
    background: rgba(26, 26, 26, .8);
    border: 1px solid rgba(var(--primary-rgb, 196, 14, 46), .22);
    border-radius: 999px;
    box-shadow: none;
    transform: none;
    color: #aaa;
    font-family: inherit;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: normal;
    text-transform: none;
    line-height: 1.4;
    cursor: pointer;
    user-select: none;
    transition: color .2s, background .2s, border-color .2s;
}
html[data-dashboard="draconium-min"] :is(.sub-pill, .filter-pill, .faq-cat-pill, .event-pill, .sub-tab, .kt-subtab, .mb-segbtn, .an-range-btn, .view-mode-btn, .pc-subtab):hover {
    color: #fff;
    border-color: rgba(var(--primary-rgb, 196, 14, 46), .5);
    box-shadow: none;
    transform: none;
}
html[data-dashboard="draconium-min"] :is(.sub-pill, .filter-pill, .faq-cat-pill, .event-pill, .sub-tab, .kt-subtab, .mb-segbtn, .an-range-btn, .view-mode-btn, .pc-subtab):is(.active, .on) {
    background: var(--gradient-active, var(--gradient, linear-gradient(100deg, var(--primary, #C40E2E), var(--secondary, #7A0920))));
    color: #fff;
    border-color: transparent;
    box-shadow: none;
}
html[data-dashboard="draconium-min"] .view-mode-btn svg { width: 13px; height: 13px; }

/* Keyboard focus ring survives every box-shadow reset above. */
html[data-dashboard="draconium-min"] :is(.cat-tab, .friend-cat-tab, .mc-tab, .category-tab, .content-tab, .kt-tab, .an-tab, .set-tab, .log-tab, .tabs .tab, .section-tabs .tab-btn, .sub-pill, .filter-pill, .faq-cat-pill, .event-pill, .sub-tab, .kt-subtab, .mb-segbtn, .an-range-btn, .view-mode-btn, .pc-subtab):focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(var(--primary-rgb, 196, 14, 46), .45);
}
