/*
 * Reactions plugin — flatbb-inspired pill bar + picker popover,
 * styled to inherit the active InstantCMS theme's design tokens.
 *
 * The user's theme defines a palette of CSS variables per theme state
 * (light / gray / blue / dark / new / git / lightblue — switched via
 * :root[data-state="..."]). We pull those vars so the bar matches every
 * theme automatically:
 *
 *   --background-light-color   panel background (white in light, #1e293b in blue, etc.)
 *   --body-bg                  slightly darker than the panel — used for hover
 *   --background-light-color-rgb   same color as rgb triplet (for rgba() mixing)
 *   --dark-color               primary text
 *   --light-color              muted text
 *   --gc-border-light          borders
 *   --current-user-color       the theme's "this is YOU" teal (#00a78d) — perfect for active
 *   --author                   soft teal tint used for "current user" highlights — perfect for active bg
 *   --primary                  link blue
 *   --shadow-color             drop shadow color (rgba)
 *   --border-radius            theme's standard radius
 *
 * All --reactions-* vars below are MAPS to the theme vars, with hardcoded
 * fallbacks for installs on a different InstantCMS theme that doesn't
 * define these tokens.
 *
 * Markup contract (matches what reactions::renderBarHtml() emits):
 *
 *   <div class="reactions" data-ctype-id data-item-id data-reactions data-max-inline>
 *     <div class="reactions-pills">
 *       <span class="reactions-pill [active]" data-reaction-emoji>
 *         <emoji><span class="reactions-count">N</span>
 *       </span>
 *       <details class="reactions-more">
 *         <summary>+N more</summary>
 *         <span class="reactions-more-list">...pills...</span>
 *       </details>
 *     </div>
 *     <button class="reactions-add" data-reaction-picker-toggle aria-expanded>
 *       <svg>...</svg>
 *     </button>
 *     <div class="reactions-picker" data-reaction-picker hidden>
 *       <div class="reactions-picker-grid">
 *         <button class="reactions-picker-item [active]" data-reaction-emoji>emoji</button>
 *       </div>
 *     </div>
 *   </div>
 */

:root {
    /* ---- maps to the active theme's tokens (with safe hardcoded fallbacks) ---- */
    --reactions-bg:            var(--background-light-color, #ffffff);
    --reactions-bg-hover:      var(--body-bg, #f3f4f6);
    --reactions-bg-soft:       var(--author, rgba(0, 167, 141, 0.15));
    --reactions-border:        var(--gc-border-light, #bac7d8);
    --reactions-border-hover:  var(--gc-border-light, #94a3b8);
    --reactions-brand:         var(--current-user-color, #00a78d);
    --reactions-brand-soft:    var(--author, rgba(0, 167, 141, 0.15));
    --reactions-text:          var(--dark-color, #1f2937);
    --reactions-text-muted:    var(--light-color, #6b7280);
    --reactions-text-subtle:   var(--light-color, #9ca3af);
    --reactions-radius:        var(--border-radius, 0.5rem);
    --reactions-radius-sm:     0.2rem;
    --reactions-shadow:        0 4px 12px var(--shadow-color, rgba(0, 0, 0, 0.08));
    --reactions-font-xs:       0.875rem;
    --reactions-font-sm:       1rem;
    --reactions-size:          1rem;       /* emoji glyph size */
}

/* ---------------------------------------------------------------- bar */

.reactions {
    display: flex;
    align-items: center;
    gap: 3px;
    flex-wrap: wrap;
    margin-top: 10px;
    position: relative;
    /* The body has a 1px text-shadow for legibility on dark themes; on
       small pill text + emoji that becomes blurry, so kill it locally. */
    text-shadow: none;
}

/* When the bar is rendered inside .info_bar (BEFORE the JS placement
   routine moves it out), HIDE it entirely. This eliminates the
   flash-of-wrong-position on page load — the user never sees the bar
   in the info_bar; it just appears above the info_bar once JS has run.
   
   How it works:
     1. Server renders bar inside .info_bar (this rule applies → invisible).
     2. JS runs (DOMContentLoaded + MutationObserver for AJAX), moves the
        wrapper to be a sibling of .info_bar, sets data-reactions-placed="1".
     3. Once moved, this rule no longer matches (wrapper is no longer a
        descendant of .info_bar), and the .icms-reactions__btn[data-reactions-placed]
        rule below takes over with display:flex → bar becomes visible
        in the right place.
   
   Risk: if JS fails to load entirely, the bar stays invisible. Acceptable
   trade-off — JS failure breaks lots of things on the site anyway, and
   the user can override this rule in their theme if they need a no-JS
   fallback (e.g. for accessibility). */
.info_bar .icms-reactions__btn {
    display: none;
}

/* Once placeReactionsBars() in reactions.js has MOVED the wrapper out of
   .info_bar (insertBefore .info_bar), the wrapper becomes a sibling of
   .info_bar — on its own row, above the vote / views / bookmark / report
   / share row, between the tags section and the info_bar.
   Style it as its own full-width row with vertical breathing room. */
.icms-reactions__btn[data-reactions-placed] {
    display: flex;
    align-items: center;
    width: 100%;
    margin: 0.5rem 0 0.75rem 0;
    padding: 0;
    /* The .bar_item class (still on the wrapper from the original info_bar
       injection) doesn't have its own styling outside .info_bar in this
       theme, so we control everything here. */
}
/* The inner .reactions still needs its own margin-top so the pills sit
   nicely below the tags / content above. */
.icms-reactions__btn[data-reactions-placed] .reactions {
    margin-top: 0;
    width: 100%;
}

.reactions-pills {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-wrap: wrap;
    min-width: 0;
}

/* ---------------------------------------------------------------- pill */

.reactions-pill {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 8px 3px 5px;
    border-radius: 999px;                       /* pill shape, not theme radius */
    background: var(--reactions-bg);
    border: 1px solid var(--reactions-border);
    cursor: pointer;
    font-size: var(--reactions-size);            /* emoji glyph size */
    line-height: 1.4;
    color: var(--reactions-text);
    user-select: none;
    text-decoration: none;
    transition: background .12s, border-color .12s, transform .12s, filter .12s;
}

/* Count inside the pill — smaller, tabular, muted. Has its own font-size
   so the per-ctype emoji-size override (.info_bar .reactions .reactions-pill
   { font-size: 24px }) doesn't accidentally scale the count too. */
.reactions-pill .reactions-count {
    font-size: var(--reactions-font-xs);
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    color: var(--reactions-text-muted);
}

.reactions-pill:hover {
    background: var(--reactions-bg-hover);
    border-color: var(--reactions-border-hover);
    /* Match the theme's button-hover convention: a subtle brightness bump. */
    filter: brightness(1.05);
}

.reactions-pill:active {
    transform: scale(.94);
}

/* Active pill = the visitor has this reaction set. Uses the theme's
   --current-user-color (teal in their palette) — the same color the theme
   uses to highlight the current user's own comments, so it reads as
   "this is YOU" in any of the 7 theme states. */
.reactions-pill.active {
    background: var(--reactions-brand-soft);
    border-color: var(--reactions-brand);
    color: var(--reactions-brand);
}

.reactions-pill.active .reactions-count {
    color: var(--reactions-brand);
}

.reactions-pill[aria-disabled="true"] {
    cursor: default;
    opacity: .85;
}

.reactions-pill[aria-disabled="true"]:hover {
    background: var(--reactions-bg);
    border-color: var(--reactions-border);
    filter: none;
}

/* ---------------------------------------------------------------- "+N more" */

.reactions-more {
    display: inline-flex;
    align-items: center;
}

.reactions-more > summary {
    list-style: none;
    cursor: pointer;
    font-size: var(--reactions-font-xs);
    color: var(--reactions-text-subtle);
    padding: 3px 6px;
    border-radius: 999px;
    user-select: none;
    transition: color .12s;
}

.reactions-more > summary::-webkit-details-marker {
    display: none;
}

.reactions-more > summary:hover {
    color: var(--reactions-brand);
    text-decoration: underline;
}

.reactions-more[open] > summary {
    color: var(--reactions-brand);
}

.reactions-more-list {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    flex-wrap: wrap;
}

/* ---------------------------------------------------------------- circular add button */

.reactions-add {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    border: 1px solid var(--reactions-border);
    background: transparent;
    color: var(--reactions-text-muted);
    cursor: pointer;
    padding: 0;
    text-shadow: none;
    transition: background .12s, border-color .12s, color .12s, transform .12s, filter .12s;
}

.reactions-add:hover {
    background: var(--reactions-brand-soft);
    border-color: var(--reactions-brand);
    color: var(--reactions-brand);
    filter: brightness(1.05);
}

.reactions-add:active {
    transform: scale(.92);
}

.reactions-add svg {
    width: 16px;
    height: 16px;
}

.reactions-add[aria-expanded="true"] {
    background: var(--reactions-brand-soft);
    border-color: var(--reactions-brand);
    color: var(--reactions-brand);
}

/* ---------------------------------------------------------------- picker popover */

/* IMPORTANT: position:fixed, NOT position:absolute.
 *
 * The picker used to be position:absolute, which positioned it relative
 * to the .reactions bar (which has position:relative). That worked — but
 * only when no ancestor of .reactions had overflow:hidden. On typical
 * InstantCMS 2 themes, the content item card / .icms-content-fields /
 * .info_bar wrapper often has overflow:hidden (for clearfix, rounded
 * corners, or to clip long content), and that clips the picker even
 * though it has z-index:50. Cranking z-index doesn't help — z-index
 * only affects stacking order, not clipping.
 *
 * position:fixed escapes overflow:hidden clipping entirely because the
 * picker is positioned relative to the viewport, not any ancestor. The
 * trade-off is that we lose the automatic "anchor below the bar"
 * positioning — we have to compute top/left in JS from the bar's
 * getBoundingClientRect().
 *
 * Until JS positions the picker, we hide it via opacity:0 + visibility:hidden
 * so there's no flash of picker-at-top-left-of-viewport.
 */
.reactions-picker {
    position: fixed;
    top: 0;
    left: 0;
    /* Will be overwritten by JS via inline style. These initial values
       just keep the picker off-screen until JS positions it. */
    transform: translateY(-200vh);
    z-index: 9999;
    min-width: 200px;
    max-width: min(90vw, 320px);
    padding: 6px;
    background: var(--reactions-bg);
    border: 1px solid var(--reactions-border);
    border-radius: var(--reactions-radius);
    box-shadow: var(--reactions-shadow);
    animation: reactions-pop .12s ease-out;
}

.reactions-picker[hidden] {
    display: none;
}

/* When JS has positioned the picker (data-picker-placed="1"), reset the
   off-screen transform and use the JS-set top/left. */
.reactions-picker[data-picker-placed] {
    transform: none;
}

.reactions-picker-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(32px, 1fr));
    gap: 2px;
}

.reactions-picker-item {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    border: none;
    background: transparent;
    border-radius: var(--reactions-radius-sm);
    cursor: pointer;
    font-size: 20px;
    line-height: 1;
    padding: 0;
    color: inherit;
    transition: background .1s, transform .1s;
}

.reactions-picker-item:hover {
    background: var(--reactions-bg-hover);
    transform: scale(1.15);
}

/* Active state on a picker item = the visitor has this reaction set.
   Same teal as the active pill, with an inset ring instead of a soft bg
   (the picker items are smaller, the ring reads clearer than a tint). */
.reactions-picker-item.active {
    background: var(--reactions-brand-soft);
    box-shadow: inset 0 0 0 2px var(--reactions-brand);
}

@keyframes reactions-pop {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: translateY(0); }
}

/* Reduced motion: kill the subtle scale/transform animations. */
@media (prefers-reduced-motion: reduce) {
    .reactions-pill,
    .reactions-add,
    .reactions-picker-item,
    .reactions-picker {
        transition: none;
        animation: none;
    }
}

/* Mobile: tighten the bar so it doesn't take a full row on a 360px screen.
   Match the theme's mobile breakpoint conventions (max-width: 767.98px
   is the theme's "sm" cutoff). */
@media (max-width: 640px) {
    .reactions { margin-top: 6px; }
    .icms-reactions__btn[data-reactions-placed] {
        margin: 0.4rem 0 0.5rem 0;
    }
}

/* ---------------------------------------------------------------- Top reactions widget */

.reactions-top-list {
    display: flex;
    flex-direction: column;
    gap: 0;
}

.reactions-top-item {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 10px 0;
    border-bottom: 1px solid var(--reactions-border);
}

.reactions-top-item:first-child { padding-top: 0; }
.reactions-top-item:last-child  { border-bottom: none; padding-bottom: 0; }

.reactions-top-topic {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: var(--reactions-font-sm);
    font-weight: 600;
    color: var(--reactions-text);
    text-decoration: none;
    transition: color .12s;
}

.reactions-top-topic:hover {
    color: var(--reactions-brand);
}

.reactions-top-breakdown {
    display: flex;
    align-items: center;
    gap: 4px;
    flex-wrap: wrap;
}

.reactions-top-chip {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    font-size: var(--reactions-font-xs);
    color: var(--reactions-text-muted);
    font-variant-numeric: tabular-nums;
    line-height: 1.4;
}

.reactions-top-chip-more,
.reactions-top-chip-total {
    color: var(--reactions-text-subtle);
    font-weight: 600;
}

.reactions-top-sep {
    color: var(--reactions-text-subtle);
    font-size: var(--reactions-font-xs);
    user-select: none;
}

.reactions-top-body {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: var(--reactions-font-sm);
    line-height: 1.4;
    color: var(--reactions-text-muted);
    text-decoration: none;
    transition: color .12s;
}

.reactions-top-body:hover {
    color: var(--reactions-brand);
}
