/* ==========================================================================
   Sociable (com_sociable) · extension bridge · Studio community kit
   --------------------------------------------------------------------------
   Sections 1-5 are kit-owned and byte-identical in Vesper, Quorum and Mimeo.
   Edit them in template-studio/kit/community/tpl/media/css/ext/sociable.css and
   run sync-kit.mjs for all three templates. Section 6 belongs to the template.

   Loaded by PageContext::useExtension('sociable') on pages that mount the SPA
   (option com_sociable, or the com_sociable.css asset) and by the chromes around
   mod_sociable_* modules. Bootstrap is OFF on Sociable pages (contract 2.1): its
   !important utilities would override the SPA's same-named Tailwind classes.

   App roots: every .sociable-app island: the mount #sociable-<view> plus the
   portals on <body> (#sociable-modal-root.sociable-app and one div.sociable-app
   per open dropdown). ThemeProvider writes the SPA palette INLINE on each
   island; author !important custom properties beat inline normal ones.

   Colour contract: the SPA uses --color-primary both as a fill (text on it is
   --color-text-inverse) and as text (links, active navigation). It maps to the
   link colour with the ground as its inverse: AA in every preset and scheme.
   Only --ec-* / --ts-* names are read, so no Sociable name (--color-*,
   --font-body) is ever declared on :root and none can resolve to itself.
   ========================================================================== */

/* 1. Variable map ----------------------------------------------------------- */

.sociable-app {
    --color-primary: var(--ts-link) !important;
    --color-primary-light: var(--ts-link-hover) !important;
    --color-primary-dark: var(--ts-link-hover) !important;
    --color-primary-rgb: var(--ts-link-rgb) !important;
    --color-bg-primary: var(--ec-bg) !important;
    --color-bg-secondary: var(--ec-surface-2) !important;
    --color-bg-tertiary: var(--ec-surface-2) !important;
    --color-surface: var(--ec-surface) !important;
    --color-surface-hover: var(--ec-surface-2) !important;
    --color-surface-border: var(--ec-border) !important;
    --color-surface-elevated: var(--ec-surface) !important;
    --color-border: var(--ec-border) !important;
    --color-control-border: var(--ts-control) !important;
    --color-text-primary: var(--ec-fg) !important;
    --color-text-secondary: var(--ec-fg-2) !important;
    --color-text-muted: var(--ec-fg-2) !important;
    --color-text-tertiary: var(--ec-fg-2) !important;
    --color-text-inverse: var(--ec-bg) !important;
    --color-success: var(--ts-success) !important;
    --color-success-light: var(--ts-success-bg) !important;
    --color-warning: var(--ts-warning) !important;
    --color-warning-light: var(--ts-warning-bg) !important;
    --color-error: var(--ts-danger) !important;
    --color-error-light: var(--ts-danger-bg) !important;
    --color-info: var(--ts-info) !important;
    --color-info-light: var(--ts-info-bg) !important;
    --font-body: var(--ec-font-body) !important;
    --font-heading: var(--ec-font-display) !important;
    --card-radius: var(--ec-radius) !important;
    --btn-radius: var(--ec-btn-radius) !important;
    --input-radius: var(--ec-btn-radius) !important;
}

/* The danger fill keeps --color-text-inverse (the ground) in the SPA; the
   danger tint is the AA text on it in both schemes. */
.sociable-app .btn-danger {
    color: var(--ts-danger-bg);
}

/* 2. Containment ------------------------------------------------------------ */

/* The SPA ships its own reset under .sociable-app (0,1,1); the
   template has no bare element rules (contract 2.4) and Bootstrap is off here
   (measured: zero template-caused computed-style changes inside the islands). */

/* Rich text (event, group, post): the SPA reset zeroes its margins; restore a flow rhythm (0,2,0 beats it). */
.sociable-app .prose > * + * {
    margin-block-start: 0.85em;
}

.sociable-app .prose :is(ul, ol) {
    padding-inline-start: 1.5em;
    list-style: disc;
}

.sociable-app .prose ol {
    list-style: decimal;
}

.sociable-app .prose blockquote {
    padding-inline-start: 1em;
    border-inline-start: 3px solid var(--ec-border);
}

/* 3. Leak neutralisers ------------------------------------------------------ */

/* None. Every Sociable selector is scoped to .sociable-app (verified in the
   built CSS and measured: zero changes outside the islands). */

/* 4. Default module markup -------------------------------------------------- */

/* The four modules print an inline <style> whose variables sit on an ID
   (#mod-sociable-<name>-<id>) and switch on html[data-color-scheme]; !important
   on the module class wins over both, and the tokens follow the page scheme. */
.mod-sociable-feed {
    --sfeed-bg: var(--ec-surface) !important;
    --sfeed-border: var(--ec-border) !important;
    --sfeed-border-soft: var(--ec-border) !important;
    --sfeed-text: var(--ec-fg) !important;
    --sfeed-muted: var(--ec-fg-2) !important;
    --sfeed-muted-hover: var(--ec-fg) !important;
    --sfeed-media-bg: var(--ec-surface-2) !important;
    --sfeed-primary: var(--ts-link) !important;
    --sfeed-primary-soft: var(--ts-tint) !important;
    --sfeed-shadow: var(--ts-overlay-shadow) !important;
}

.mod-sociable-groups {
    --sgroups-bg: var(--ec-surface) !important;
    --sgroups-border: var(--ec-border) !important;
    --sgroups-border-soft: var(--ec-border) !important;
    --sgroups-text: var(--ec-fg) !important;
    --sgroups-muted: var(--ec-fg-2) !important;
    --sgroups-placeholder: var(--ec-fg-2) !important;
    --sgroups-media-start: var(--ec-surface-2) !important;
    --sgroups-media-end: var(--ec-surface-2) !important;
    --sgroups-primary: var(--ts-link) !important;
    --sgroups-primary-soft: var(--ts-tint) !important;
    --sgroups-shadow: var(--ts-overlay-shadow) !important;
}

.mod-sociable-members {
    --smem-radius: var(--ec-radius) !important;
    --smem-card-bg: var(--ec-surface) !important;
    --smem-border: var(--ec-border) !important;
    --smem-primary: var(--ts-link) !important;
    --smem-primary-hover: var(--ts-link-hover) !important;
    --smem-text: var(--ec-fg) !important;
    --smem-muted: var(--ec-fg-2) !important;
    --smem-badge-bg: var(--ec-surface-2) !important;
    --smem-badge-text: var(--ec-fg) !important;
    --smem-verified: var(--ts-info) !important;
    --smem-shadow: var(--ec-shadow) !important;
    --smem-shadow-hover: var(--ts-overlay-shadow) !important;
}

.mod-sociable-notifications {
    --snot-primary: var(--ts-link) !important;
    --snot-primary-hover: var(--ts-link-hover) !important;
    --snot-bg: var(--ec-surface) !important;
    --snot-border: var(--ec-border) !important;
    --snot-text: var(--ec-fg) !important;
    --snot-muted: var(--ec-fg-2) !important;
    --snot-unread-bg: var(--ts-tint) !important;
    --snot-unread-dot: var(--ts-signal) !important;
    --snot-shadow: var(--ts-overlay-shadow) !important;
    --snot-hover: var(--ec-surface-2) !important;
    --snot-item-border: var(--ec-border) !important;
    --snot-item-hover: var(--ec-surface-2) !important;
    --snot-unread-hover: var(--ec-surface-2) !important;
    --snot-scrollbar: var(--ts-control) !important;
    --snot-badge-border: var(--ec-surface) !important;
    --snot-radius: var(--ec-radius) !important;
}

/* The feed card's author and time links sit on 19.5px lines, stacked: each
   gets a 24px target (WCAG 2.5.8). */
.mod-sociable-feed :is(.sfeed-card__author, .sfeed-card__time-link) {
    display: inline-flex;
    align-items: center;
    min-block-size: 1.5rem;
}

/* Group-type badges are hard-coded light hex pairs; the type is also written
   as text, so the badge becomes a neutral tag that works in both schemes. */
.mod-sociable-groups .sgroup-badge {
    border-radius: var(--ec-btn-radius);
    background: var(--ec-surface-2) !important;
    color: var(--ec-fg) !important;
}

/* Filled buttons hard-code white text on the primary fill (groups "Join",
   members "View profile", and the outline buttons' hover fill): the text on
   the link-colour fill is the ground. */
.mod-sociable-groups .sgroup-btn,
.mod-sociable-groups .sgroup-btn:hover,
.mod-sociable-members .smem-btn--primary,
.mod-sociable-members .smem-btn--primary:hover,
.mod-sociable-members .smem-btn--outline:hover {
    color: var(--ec-bg) !important;
}

/* The unread count: the danger pair instead of #ef4444 on white text. */
.mod-sociable-notifications .snot-badge {
    background: var(--ts-danger) !important;
    color: var(--ts-danger-bg) !important;
}

/* A 340px dropdown centred on a bell near the right edge runs off a phone:
   pin it to the trigger's inline end and cap it to the viewport. */
@media (max-width: 30rem) {
    .mod-sociable-notifications .snot-panel--dropdown {
        inset-inline: auto 0 !important;
        min-inline-size: 0 !important;
        inline-size: min(340px, calc(100dvw - 2rem)) !important;
        transform: none !important;
        transform-origin: top right !important;
    }
}

/* Share bar of plg_content_sociable (after articles; not overridable, and it
   ships no CSS): its SVGs carry no width/height. */
.sociable-share-buttons {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.75rem;
    margin-block: 1.5rem;
}

.sociable-share-label {
    color: var(--ec-fg-2);
    font-weight: 600;
}

.sociable-share-list {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.sociable-share-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-block-size: 44px;
    min-inline-size: 44px;
    justify-content: center;
    padding: 0.5rem 0.875rem;
    border: 1px solid var(--ts-control);
    border-radius: var(--ec-btn-radius);
    background: var(--ec-surface);
    color: var(--ec-fg);
    font-weight: 600;
    line-height: 1.2;
    text-decoration: none;
}

.sociable-share-btn:hover {
    border-color: var(--ec-fg);
    color: var(--ec-fg);
}

.sociable-share-icon {
    display: inline-flex;
    flex-shrink: 0;
}

.sociable-share-icon svg {
    display: block;
    inline-size: 1.1em;
    block-size: 1.1em;
}

.sociable-share-buttons--sm .sociable-share-btn {
    padding-inline: 0.625rem;
    font-size: 0.875rem;
}

.sociable-share-buttons--lg .sociable-share-btn {
    padding-inline: 1.125rem;
    font-size: 1.0625rem;
}

/* 5. Page frame ------------------------------------------------------------- */

/* Below 768px the SPA pulls itself out of the content column by half of
   --bs-gutter-x on each side (default 15px); twice the template gutter makes
   the breakout land exactly on the viewport edges. */
.ts-app--sociable #ts-main {
    --bs-gutter-x: calc(2 * var(--ec-gut));
}

/* The SPA toolbar carries its own search and bell: the template's header copies
   (the account block's bell, the header search, a mod_sociable_notifications
   bell) stand down on Sociable pages (contract 5.3). */
.ts-app--sociable .ts-header__modules :is(.ts-account__bell, .ts-search--header, .mod-sociable-notifications) {
    display: none;
}

/* Below 1024px the SPA pins a 60px bottom navigation to the viewport: the page
   footer keeps its last line clear of it. */
@media (max-width: 63.9999rem) {
    .ts-app--sociable .ts-footer {
        padding-block-end: calc(60px + env(safe-area-inset-bottom, 0px));
    }
}

/* The pre-hydration placeholder ("Loading..." under an empty spinner div) ships
   no CSS: a quiet, centred, reserved block instead of a bare line. */
:is(.sociable-feed__loading, .sociable-groups__loading, .sociable-group__loading,
    .sociable-events__loading, .sociable-event__loading, .sociable-profile__loading,
    .sociable-notifications__loading, .sociable-topic__loading, .sociable-login__loading,
    .sociable-register__loading) {
    display: grid;
    place-items: center;
    min-block-size: 12rem;
    color: var(--ec-fg-2);
}

/* @ts-kit section-6 begin: 6. Design skin (template-owned; sync-kit.mjs keeps everything between these two markers) */
/* Quorum: square cards, buttons, chips and bubbles (people stay round), no shadows, Big Shoulders
   headings, square date tiles; the kit already zeroes --card/--btn/--input-radius. */
html .sociable-app.sociable-app :is([class~="rounded-lg"], [class~="rounded-xl"], [class~="rounded-2xl"], [class*="rounded-["], .sociable-event-card__date, .sociable-event-card__chip, kbd) { border-radius: 0; }
html .sociable-app.sociable-app :is(button, a, span[class*="px-"], input)[class~="rounded-full"] { border-radius: 0; }
html .sociable-app.sociable-app [class*="shadow-"]:not(:focus-visible) { box-shadow: none; }
html .sociable-app.sociable-app :is(h1, h2) { font-weight: 700; line-height: 1.05; letter-spacing: 0; }
html .sociable-app.sociable-app h1:not(.truncate) { font-size: clamp(2.5rem, 2.3vw + 1.9rem, 3.5rem); }
/* The group and profile title sits in the header row that overlaps the cover (-mt-7): it keeps
   the display face at a size that clears the image and does not truncate a long name. */
html .sociable-app.sociable-app h1.truncate { font-size: 2rem; line-height: 1.05; }
html .sociable-app.sociable-app [class~="-mt-7"]:has(h1.truncate) { margin-block-start: 0; padding-block-start: var(--q-s3); }
/* Pill tab bars (Newest posts / Latest activity) are square like every other control. */
html .sociable-app.sociable-app div[class~="rounded-full"]:has(> button) { border-radius: 0; }
html .sociable-app.sociable-app .sociable-event-card__title { font-size: 1.25rem; font-weight: 700; line-height: 1.1; }
/* Initials avatars: Sociable paints them white on its own eight-colour palette (inline style,
   2.2-3.8:1). Each palette colour maps to one of Quorum's seven initials tones (design spec §6.6),
   all AA with white. */
html .sociable-app.sociable-app div.text-white[style*="rgb(74, 144, 217)"] { background-color: var(--q-avatar-1) !important; }
html .sociable-app.sociable-app div.text-white[style*="rgb(39, 174, 96)"] { background-color: var(--q-avatar-2) !important; }
html .sociable-app.sociable-app div.text-white[style*="rgb(231, 76, 60)"] { background-color: var(--q-avatar-3) !important; }
html .sociable-app.sociable-app div.text-white[style*="rgb(155, 89, 182)"] { background-color: var(--q-avatar-4) !important; }
html .sociable-app.sociable-app div.text-white[style*="rgb(243, 156, 18)"] { background-color: var(--q-avatar-5) !important; }
html .sociable-app.sociable-app div.text-white[style*="rgb(26, 188, 156)"] { background-color: var(--q-avatar-6) !important; }
html .sociable-app.sociable-app div.text-white[style*="rgb(233, 30, 99)"] { background-color: var(--q-avatar-7) !important; }
html .sociable-app.sociable-app div.text-white[style*="rgb(63, 81, 181)"] { background-color: var(--q-avatar-1) !important; }
/* Avatar stacks: the app overlaps 24px discs by half, which cuts the initials; a quarter overlap
   and a surface ring keep every pair of letters whole. */
html .sociable-app.sociable-app [class*="-space-x-"] > [class~="rounded-full"], html .sociable-app.sociable-app .sociable-event-card__avatars > * { inline-size: 1.75rem !important; block-size: 1.75rem !important; margin-inline-end: 0 !important; border: 2px solid var(--ec-surface); font-size: 0.6875rem; }
html .sociable-app.sociable-app [class*="-space-x-"] > :not(:first-child), html .sociable-app.sociable-app .sociable-event-card__avatars > * + * { margin-inline-start: -0.375rem !important; }
/* Events as a gap-ruled board: 1px hairlines between square cells instead of floating cards
   (the grid's gap and equal heights are set with the groups board below). */
html .sociable-app.sociable-app .sociable-events__grid > .sociable-event-card { border: 0 !important; outline: var(--q-hair-w) solid var(--ec-border); }
/* Groups directory: the search field is a square control; the group cards are one gap-ruled
   board (1px hairlines, no floating cards, equal heights); titles in Big Shoulders at 20px, the
   two-line description in body text (16px, addendum A4.1), meta and the Join button at 14px. */
html .sociable-app.sociable-app div[class~="rounded-full"]:is([class*="px-"], [class~="h-9"]) { border-radius: 0; }
html .sociable-app.sociable-app [class~="grid"][class*="grid-cols"]:has(> * h3[class*="text-[13.5px]"]), html .sociable-app.sociable-app .sociable-events__grid { gap: var(--q-hair-w) !important; align-items: stretch !important; }
html .sociable-app.sociable-app [class~="grid"][class*="grid-cols"]:has(> * h3[class*="text-[13.5px]"]) > * { border: 0 !important; outline: var(--q-hair-w) solid var(--ec-border); }
:root .sociable-app.sociable-app h3[class*="text-[13.5px]"] { font-size: 1.25rem; font-weight: 700; line-height: 1.1; }
:root .sociable-app.sociable-app p[class~="text-xs"][class*="line-clamp"] { font-size: 1rem; line-height: 1.5; }
:root .sociable-app.sociable-app :is(p[class~="text-xs"], input[class*="text-[12.5px]"], span.truncate), :root .sociable-app.sociable-app :is(span, button, a)[class*="text-[11.5px]"], :root .sociable-app.sociable-app :is(span, button, a)[class*="text-[12.5px]"], :root .sociable-app.sociable-app button[class~="text-xs"], :root .sociable-app.sociable-app h3[class*="text-[13.5px]"] ~ * span { font-size: 0.875rem; }
/* Event cards: date, place and host at the 14px metadata floor (design spec §4.2). */
:root .sociable-app.sociable-app .sociable-event-card :is(span, time, strong):not(.sociable-event-card__day, .sociable-event-card__month, .sociable-event-card__chip) { font-size: 0.875rem; }
/* The notification count on the bell and the sidebar: Sociable paints it white 10px on its amber
   (2.0-2.6:1). A square accent tag with a surface ring, as in Quorum's header (design spec §5.2). */
:root .sociable-app.sociable-app span[class~="rounded-full"][class*="min-w-[16px]"] { min-inline-size: 1.25rem; block-size: 1.25rem; border-radius: 0; background-color: var(--ec-accent); box-shadow: 0 0 0 2px var(--ec-surface); color: var(--ec-accent-fg); font-size: 0.75rem; font-weight: 700; }
/* Sociable's accent is its own amber (#e08e00: chips, the points card, the zap icon, a group
   initial tile), 2.3-3.8:1 and a second yellow. Quorum rations yellow to the signal strip (§1.8):
   the accent is the Quorum teal, its text the on-tint teal on the accent tint (AA both schemes). */
html .sociable-app.sociable-app { --color-accent: var(--ec-accent) !important; --color-accent-light: var(--ec-accent) !important; --color-accent-text: var(--ts-on-tint) !important; --color-accent-bg: var(--ec-accent-soft) !important; }
/* Flat, never gradients (§1): the default profile and group cover is a tint cell under the rule. */
html .sociable-app.sociable-app [style*="linear-gradient"] { border-block-start: var(--q-rule-w) solid var(--q-rule); background: var(--q-tint) !important; }
/* Fallback avatars ("?" in white on the muted text colour, 2.2:1 in dark) take an initials tone. */
html .sociable-app.sociable-app div.text-white[style*="--color-text-muted"] { background-color: var(--q-avatar-1) !important; }
/* The shared notification count (lib_shondalai_core header): a square accent tag with a
   surface ring (design spec §5.2), not Tailwind's blue disc. */
html :is(.sociable-app, #cjforum-root) button > span[class~="bg-blue-600"][class~="rounded-full"] { border-radius: 0; background-color: var(--ec-accent); box-shadow: 0 0 0 2px var(--ec-surface); color: var(--ec-accent-fg); font-size: 0.75rem; font-weight: 700; }
/* Page title on the container edge, as on every page (§9; phones: the app is full-bleed). */
@media (width >= 48rem) { html .sociable-app.sociable-app main.min-w-0, html .sociable-app.sociable-app main.min-w-0 > :is(.sociable-events, .max-w-full) { padding-inline: 0; } }
/* Dates, times and date stamps in Overpass Mono (§1.9), as on the home. */
:root .sociable-app.sociable-app :is(time, .sociable-event-card__month) { font-family: var(--q-font-mono); font-weight: 600; }
/* The app's phone drawer assumes its own 56px bar tops the viewport: on Quorum it starts at the top
   instead of cutting through the notice strip and header. */
@media (width < 64rem) {
    html .sociable-app.sociable-app .fixed[class~="top-14"][class~="h-screen"] { top: 0; height: 100dvh; }
}
/* @ts-kit section-6 end */
