/* === FEED STYLES === */
.feed-header {
    display: flex;
    max-width: 600px;
    margin: 0 auto;
    padding: var(--spacing-8) 0;
}

.feed-header h1 {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--spacing-12);
    margin-bottom: var(--spacing-8);
}

.feed-controls {
    display: flex;
    justify-content: center;
    align-items: center;
    margin-bottom: var(--spacing-16);
}

.activity-toggle {
    display: flex;
    align-items: center;
    gap: var(--spacing-12);
}

.feed-subtitle {
    color: var(--text-sub);
    font-size: 16px;
    margin: 0;
}

/* .empty-feed + .empty-feed-icon + .feed-actions entfernt — genutzt wird
   jetzt die generische .empty-state-Komponente aus main.css
   (docs/DESIGN_GUIDE.md §5.6). */

/* Feed Container */
.feed-container {
    max-width: 600px;
    min-height: 200px;
    margin: 0 auto;
}

/* Feed Date Separators */
.feed-date-separator {
    display: flex;
    align-items: center;
    gap: var(--spacing-12);
    padding: var(--spacing-8) 0 var(--spacing-4);
    margin-bottom: var(--spacing-8);
}

.feed-date-separator::after {
    content: '';
    flex: 1;
    height: 1px;
    background: var(--background-hover);
}

.feed-date-label {
    font-size: 13px;
    font-weight: var(--fw-regular);
    color: var(--text-sub);
    white-space: nowrap;
    letter-spacing: 0.3px;
    text-transform: none;
}

/* Feed Items */
.feed-item {
    display: flex;
    /* Geaendert 03.10.: war --background-light. Gilt fuer Light und Dark,
       da das Token je Theme neu definiert wird. */
    background: var(--background);
    margin-bottom: var(--spacing-16);
    border-radius: var(--spacing-8);
    position: relative;
    flex-direction: column;
}

.feed-group {
    padding: var(--spacing-16) var(--spacing-16) var(--spacing-8) var(--spacing-16);
    display: flex;
    flex-direction: row;
    gap: var(--spacing-16);
}

.feed-item .feed-header {
    display: flex;
    align-items: flex-start;
    gap: var(--spacing-16);
    max-width: none;
    margin: 0;
    padding: var(--spacing-16) var(--spacing-16) var(--spacing-8);
    flex: 1;
    min-width: 0;
}

.rating-row{
    display: table;
    border-spacing: 0 var(--spacing-8);
}

.rating-col {
    display: table-row;
}

/* Highlight-Card: Avatar-Badge + dezente rote Tönung der ganzen Card.
   Macht eine Empfehlung visuell unverwechselbar, ohne aggressiv zu sein. */
.feed-item[data-is-highlighted="1"] {
    background:
        linear-gradient(320deg, rgba(254, 45, 82, 0.1), rgba(254, 45, 82, 0.02) 100%, transparent),
        var(--background);
}

.feed-item[data-is-highlighted="1"] .feed-avatar,
.feed-item[data-is-highlighted="1"] .feed-avatar-group {
    position: relative;
}

.feed-item[data-is-highlighted="1"] .feed-avatar::after,
.feed-item[data-is-highlighted="1"] .feed-avatar-group::after {
    /* Phosphor ph-shooting-star direkt aus der bereits geladenen Webfont
       gezeichnet (codepoint U+ECFA, siehe assets/css/phosphor/regular/style.css).
       So kriegen wir das echte Icon und nicht eine Annäherung als SVG-Inline. */
    content: "\ecfa";
    font-family: 'Phosphor';
    font-weight: var(--fw-regular);
    font-style: normal;
    font-variant: normal;
    text-transform: none;
    line-height: 1;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;

    position: absolute;
    right: -4px;
    bottom: -4px;
    width: 20px;
    height: 20px;
    background: var(--accent-red, #fe2d52);
    color: #fff;
    border-radius: 50%;
    border: 2px solid var(--background-light);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    pointer-events: none;
    /* Bei merged-watchlog haben die gestackten avatare z-index 1-4
       (siehe a.feed-avatar-stacked-0..3). Badge muss darüber liegen. */
    z-index: 5;
}

span.rating-text {
    font-size: 14px;
    display: table-cell;
    padding-right: var(--spacing-8);
}

.rating-span{
    width: 28px;
    height: 28px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    font-weight: var(--fw-regular);
}

.user-rating-span{
    width: 28px;
    height: 28px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    font-weight: var(--fw-regular);
    line-height: 12px;
}

/* Basis-Padding entfernt — der Footer wird weiter unten im
   Redesign-Abschnitt vollstaendig definiert (Zeit links, Buttons rechts,
   eine Trennlinie oben). Zwei konkurrierende Regeln hatten vorher eine
   doppelte Linie erzeugt. */

.feed-avatar {
    flex-shrink: 0;
}

a.feed-avatar {
    text-decoration: none;
}

/* Merged Watchlog: Stacked Avatars */
.feed-avatar-group {
    position: relative;
    flex-shrink: 0;
    width: 56px;
    height: 48px;
}

a.feed-avatar-stacked {
    position: absolute;
    top: 0;
    display: block;
    text-decoration: none;
}

a.feed-avatar-stacked img {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    object-fit: cover;
    border: 2px solid var(--background-light);
}

a.feed-avatar-stacked-0 {
    left: 0;
    z-index: 4;
}

a.feed-avatar-stacked-1 {
    left: 18px;
    top: 10px;
    z-index: 3;
}

a.feed-avatar-stacked-2 {
    left: 4px;
    top: 22px;
    z-index: 2;
}

a.feed-avatar-stacked-3 {
    left: 22px;
    top: 24px;
    z-index: 1;
}

.feed-item .feed-body {
    flex: 1;
    min-width: 0;
}

.feed-avatar img {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    object-fit: cover;
    border: 2px solid var(--background);
}

.feed-content {
    flex: 1;
    min-width: 0;
}

.feed-content > * + * {
    margin-top: var(--spacing-8);
}

.feed-text {
    color: var(--text);
    font-size: 16px;
    line-height: 1.5;
    word-wrap: break-word;
}

.feed-text strong {
    color: var(--text-link);
    font-weight: var(--fw-regular);
    border-bottom: var(--border-champagne);
}

.feed-time {
    color: var(--text-sub);
    font-size: 14px;
    margin: 0;
}

.feed-media-link {
    margin-top: var(--spacing-12);
}

.media-link,
a.media-link,
a.media-link:visited {
    /* display: inline-flex; */
    align-items: center;
    gap: var(--spacing-4);
    color: var(--primary-color);
    text-decoration: none;
    /* padding: var(--spacing-4) var(--spacing-8); */
    border-radius: var(--spacing-4);
    transition: background-color 0.2s ease;
}

.feed-icon {
    flex-shrink: 0;
    align-self: flex-start;
    margin-top: var(--spacing-4);
}

.feed-icon i {
    font-size: 20px;
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--background);
}

/* Activity Type Colors */
.feed-item[data-activity="rating"] .feed-icon i {
    color: var(--accent-green);
    background: rgba(90, 196, 88, 0.1);
}

.feed-item[data-activity="interest"] .feed-icon i {
    color: var(--accent-red);
    background: rgba(254, 45, 82, 0.1);
}

.feed-item[data-activity="abandoned"] .feed-icon i {
    color: var(--error-color);
    background: rgba(220, 53, 69, 0.1);
}

.feed-item[data-activity="list_created"] .feed-icon i,
.feed-item[data-activity="list_item_added"] .feed-icon i {
    color: var(--primary-color);
    background: rgba(72, 168, 233, 0.1);
}

.feed-item[data-activity="follow"] .feed-icon i {
    color: var(--warning-color);
    background: rgba(255, 193, 7, 0.1);
}

.feed-item[data-activity="friendship"] .feed-icon i {
    color: var(--accent-green);
    background: rgba(90, 196, 88, 0.1);
}

.feed-item[data-activity="review"] .feed-icon i {
    color: var(--sky-blue);
    background: rgba(72, 168, 233, 0.1);
}

/* Responsive Design */
@media (max-width: 768px) {
    .feed-item {
        gap: var(--spacing-12);
    }

    .feed-avatar img {
        width: 40px;
        height: 40px;
    }

    .feed-text {
        font-size: 15px;
    }

    .feed-actions {
        flex-direction: column;
        align-items: center;
    }

    .feed-actions .button {
        width: 100%;
        max-width: 250px;
    }
}

@media (max-width: 480px) {
    .feed-header {
        padding: var(--spacing-16) 0;
    }
}

/* Loading States */
.feed-loading {
    display: flex;
    justify-content: center;
    align-items: center;
    padding: var(--spacing-64);
}

.feed-loading .spinner {
    width: 32px;
    height: 32px;
    border: 3px solid var(--grey-400);
    border-top: 3px solid var(--primary-color);
    border-radius: 50%;
    animation: spin 1s linear infinite;
}

/* Animation for new feed items */
@keyframes feedItemSlideIn {
    from {
        opacity: 0;
        transform: translateY(-20px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.feed-item.new {
    animation: feedItemSlideIn 0.3s ease-out;
}

/* Notification-Target-Highlight: wenn der User aus dem Notification-Overlay
   auf einen Community-Beitrag klickt und die Karte bereits auf der Seite
   sichtbar ist, scrollen wir hin und blinken sie kurz an. Klasse wird per
   JS gesetzt (notifications.js::openCommentOrReactionTarget) und nach 2.4s
   wieder entfernt. */
@keyframes feedItemNotifTarget {
    0%   { box-shadow: 0 0 0 3px rgba(72, 168, 233, 0.7); }
    100% { box-shadow: 0 0 0 3px rgba(72, 168, 233, 0); }
}

.feed-item--notif-target {
    animation: feedItemNotifTarget 2.4s ease-out;
}

/* === FEED LINKS === */
.feed-text a.user-link {
    color: var(--text-link);
    text-decoration: none;
    border-bottom: var(--border-champagne);
    font-weight: var(--fw-regular);
    transition: color 0.2s ease;
}

.feed-text a.user-link:hover {
    color: var(--text-link-hover);
}

.feed-text a.media-link {
    color: var(--text-link);
    text-decoration: none;
    border-bottom: var(--border-champagne);
    font-weight: var(--fw-regular);
    transition: color 0.2s ease;
}

.feed-text a.media-link:hover {
    color: var(--text-link-hover);
}

.feed-text a.season-link {
    color: var(--text-link);
    text-decoration: none;
    border-bottom: var(--border-champagne);
    font-weight: var(--fw-regular);
    transition: color 0.2s ease;
}

.feed-text a.season-link:hover {
    color: var(--text-link-hover);
}

.feed-text a.list-link {
    color: var(--text-link);
    text-decoration: none;
    border-bottom: var(--border-champagne);
    font-weight: var(--fw-regular);
    transition: color 0.2s ease;
}

.feed-text a.list-link:hover {
    color: var(--text-link-hover);
}

/* Spezifische Styles für verschiedene Feed-Typen */
.feed-item[data-activity="rating"] {
    border-radius: var(--spacing-8);
}

/* Entfernt 2026-10-02: Die Zeit steht jetzt im Footer, nicht mehr im
   Content-Block. Der Abstand kam sonst zusaetzlich zum Footer-Padding. */

/*
.feed-item[data-activity="rating"] .feed-group, .feed-item[data-activity="rating"] .feed-footer {
    border-left: 4px solid var(--accent-green);
}
 
.feed-item[data-activity="interest"] {
    border-left: 4px solid var(--accent-red);
}

.feed-item[data-activity="abandoned"] {
    border-left: 4px solid var(--error-color);
}

.feed-item[data-activity="list_created"],
.feed-item[data-activity="list_item_added"] {
    border-left: 4px solid var(--primary-color);
}

.feed-item[data-activity="follow"] {
    border-left: 4px solid var(--warning-color);
}

.feed-item[data-activity="friendship"] {
    border-left: 4px solid var(--accent-green);
} */

/* Hover-Effekte für Feed-Items */
/* .feed-item[data-activity="rating"]:hover {
    background: rgba(90, 196, 88, 0.05);
}

.feed-item[data-activity="interest"]:hover {
    background: rgba(254, 45, 82, 0.05);
}

.feed-item[data-activity="abandoned"]:hover {
    background: rgba(220, 53, 69, 0.05);
}

.feed-item[data-activity="list_created"]:hover,
.feed-item[data-activity="list_item_added"]:hover {
    background: rgba(72, 168, 233, 0.05);
}

.feed-item[data-activity="follow"]:hover {
    background: rgba(255, 193, 7, 0.05);
}

.feed-item[data-activity="friendship"]:hover {
    background: rgba(90, 196, 88, 0.05);
} */

/* Feed Reactions */
/* Trennlinie und Abstand entfernt 2026-10-02: Die Reactions sitzen jetzt
   im Footer, der seine eigene border-top hat. Beides zusammen ergab eine
   doppelte Linie. */
.feed-reactions {
    min-width: 0;
}

.emoji-reactions {
    display: flex;
    gap: var(--spacing-8);
    align-items: center;
    flex-wrap: wrap;
}

.reaction-button {
    display: inline-flex;
    align-items: center;
    gap: var(--spacing-4);
    height: 26px; /* gleiche Hoehe wie .comment-btn (feed-comments.css) */
    /* WebKit bekommt unten 2px (siehe @supports unten), Chrome/Firefox
       keine. Gemessen 2026-10-16: Owner-Screenshots + Playwright in der
       echten Feed-Seite — Vault Wissen/Emojis vertikal zentrieren. */
    padding: 0 var(--spacing-8) 0 6px;
    font-family: inherit;
    line-height: 1;
    background: var(--background);
    border: var(--border-light);
    border-radius: var(--radius-full);
    color: var(--text);
    cursor: pointer;
    transition: transform 0.15s ease, background-color 0.15s ease, border-color 0.15s ease;
    font-size: 14px;
}

.reaction-button:hover {
    background: var(--background-hover);
}

/* Eigene Reaktion: Primary-Tint + Primary-Rand (Reactions-Redesign 2026-10-16) */
.reaction-button.user-reacted {
    background: color-mix(in srgb, var(--primary-color) 18%, transparent);
    border-color: var(--primary-color);
    color: var(--text);
}

.reaction-button.user-reacted .count {
    color: var(--text);
    font-weight: var(--fw-bold);
}

.reaction-button .emoji {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 16px;
    font-size: 14px;
    line-height: 16px;
}

/* WebKit (Safari, iPhone, iOS-App) setzt Outfit und Emojis in den Chips
   ~1px tiefer als Chrome/Firefox. hanging-punctuation kennt nur WebKit.
   Gleicher Wert bei .comment-btn (feed-comments.css). */
@supports (hanging-punctuation: first) {
    .reaction-button {
        padding-bottom: 2px;
    }
}

.reaction-button .count {
    font-size: var(--font-size-xs);
    font-weight: var(--fw-regular);
    min-width: 12px;
    text-align: center;
    color: var(--text-sub);
}

/* Smiley-Button: Kreis in Hoehe von .comment-btn, Tap-Flaeche per ::before auf 46px */
.add-reaction-btn {
    position: relative;
    box-sizing: border-box;
    flex: none;
    width: 26px;
    height: 26px;
    padding: 0;
    border-radius: 50%;
    font-family: inherit;
    background: var(--background);
    border: var(--border-light);
    color: var(--text-sub);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.add-reaction-btn::before {
    content: '';
    position: absolute;
    inset: -10px;
}

.add-reaction-btn i {
    font-size: 16px;
    line-height: 1;
}

.add-reaction-btn:hover,
.add-reaction-btn[aria-expanded="true"] {
    border-color: var(--primary-color);
    color: var(--text);
    background: color-mix(in srgb, var(--primary-color) 18%, transparent);
}

/* ---- Reaction-Picker (ein Picker fuer die ganze App, feed-reactions.js) ----
   z-index ueber den Content-Modals (100000000) und dem Reaction-Info-Popup
   (100000001) — Legacy-Skala, siehe DESIGN_GUIDE §1.8. */
.reaction-picker {
    box-sizing: border-box;
    position: fixed;
    z-index: 100000003;
    width: min(340px, calc(100vw - 24px));
    padding: 6px;
    display: flex;
    flex-direction: column;
    background: var(--background-light);
    border: var(--border-light);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-lg);
    animation: reactionPickerIn 0.16s ease-out;
}

@keyframes reactionPickerIn {
    from { opacity: 0; transform: scale(0.94); }
    to   { opacity: 1; transform: scale(1); }
}

.reaction-picker-quick {
    display: flex;
    align-items: center;
    gap: 2px;
}

.reaction-picker-option {
    width: 40px;
    height: 40px;
    flex: none;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: transparent;
    font-size: 24px;
    line-height: 1;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: transform 0.12s ease, background-color 0.12s ease;
}

.reaction-picker-option:hover,
.reaction-picker-option:focus-visible {
    background: var(--background-hover);
    transform: scale(1.18);
}

.reaction-picker-more {
    margin-left: auto;
    flex: none;
    height: 36px;
    padding: 0 var(--spacing-12);
    border: none;
    border-radius: var(--radius-full);
    background: var(--background-hover);
    color: var(--text-sub);
    font-family: inherit;
    font-size: var(--font-size-sm);
    cursor: pointer;
}

.reaction-picker-more:hover {
    color: var(--text);
}

.reaction-picker-all {
    margin-top: 6px;
    padding: var(--spacing-4) 2px 2px;
    border-top: var(--border-light);
    max-height: 248px;
    overflow-y: auto;
    overscroll-behavior: contain;
}

.reaction-picker-group {
    padding: var(--spacing-8) 6px 2px;
    font-size: var(--font-size-xs);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-inactive);
}

.reaction-picker-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(40px, 1fr));
}

.reaction-picker-grid .reaction-picker-option {
    width: 100%;
}

/* Mobil: Bottom-Sheet statt Popover (Owner-Entscheidung 2026-10-16) */
.reaction-picker-scrim {
    position: fixed;
    inset: 0;
    z-index: 100000002;
    background: rgba(0, 0, 0, 0.45);
    animation: reactionScrimIn 0.18s ease-out;
}

@keyframes reactionScrimIn {
    from { opacity: 0; }
}

.reaction-picker.is-sheet {
    top: auto;
    left: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    padding: var(--spacing-8) max(var(--spacing-12), env(safe-area-inset-right, 0px)) calc(var(--spacing-12) + env(safe-area-inset-bottom, 0px)) max(var(--spacing-12), env(safe-area-inset-left, 0px));
    border-bottom: none;
    border-radius: 20px 20px 0 0;
    animation: reactionSheetIn 0.22s cubic-bezier(0.2, 0.9, 0.3, 1);
}

@keyframes reactionSheetIn {
    from { transform: translateY(100%); }
}

.reaction-picker-handle {
    width: 38px;
    height: 4px;
    margin: 2px auto var(--spacing-8);
    border-radius: 2px;
    background: var(--text-inactive);
    opacity: 0.5;
}

.reaction-picker.is-sheet .reaction-picker-quick {
    justify-content: space-between;
}

.reaction-picker.is-sheet .reaction-picker-option {
    width: 44px;
    height: 44px;
    font-size: 27px;
}

.reaction-picker.is-sheet .reaction-picker-all {
    max-height: 46vh;
}

.reaction-picker.is-sheet .reaction-picker-grid {
    grid-template-columns: repeat(auto-fill, minmax(44px, 1fr));
}

.reaction-picker.is-sheet .reaction-picker-grid .reaction-picker-option {
    width: 100%;
}

@media (prefers-reduced-motion: reduce) {
    .reaction-picker,
    .reaction-picker.is-sheet,
    .reaction-picker-scrim {
        animation: none;
    }
    .reaction-picker-option:hover,
    .reaction-picker-option:focus-visible {
        transform: none;
    }
}

/* Responsive */
@media (max-width: 768px) {
    .emoji-reactions {
        gap: var(--spacing-4);
    }
    
}

/* Neuer kreisförmiger Spinner für Feed */
.feed-loading {
    display: none;
    text-align: center;
    padding: var(--spacing-32) var(--spacing-16);
    color: var(--text-sub);
}

.loading-spinner {
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;
    gap: var(--spacing-16);
}

/* Kreisförmiger Spinner */
.spinner-circle {
    width: 40px;
    height: 40px;
    border: 3px solid var(--background-light);
    border-top: 3px solid var(--primary-color);
    border-radius: 50%;
    animation: spin-circle 1s linear infinite;
}

@keyframes spin-circle {
    0% {
        transform: rotate(0deg);
    }
    100% {
        transform: rotate(360deg);
    }
}

.spinner-text {
    color: var(--text-sub);
    font-size: 0.875rem;
    margin: 0;
}


.loading-spinner p {
    color: var(--text-sub);
    margin: 0;
}

.scroll-trigger {
    height: 1px;
    margin-bottom: 2rem;
}



/* Feed Backdrop für Rating-Beiträge */
.feed-backdrop {
    position: relative;
    width: 100%;
    height: 250px;
    background-size: cover;
    background-position: center;
    border-radius: var(--radius-md) var(--radius-md) 0 0;
    overflow: hidden;
}

.feed-backdrop-overlay {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: linear-gradient(
        to bottom,
        rgba(0, 0, 0, 0.3) 0%,
        rgba(0, 0, 0, 0.7) 100%
    );
    display: flex;
    align-items: flex-end;
    padding: var(--spacing-16);
}

.feed-backdrop-content {
    display: flex;
    gap: var(--spacing-16);
    width: 100%;
    color: var(--white);
}

.feed-backdrop .feed-avatar img {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    object-fit: cover;
    border: 2px solid var(--white);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}

.feed-backdrop .feed-content {
    flex: 1;
    min-width: 0;
}

.feed-backdrop .feed-content > * + * {
    margin-top: var(--spacing-8);
}

.feed-backdrop .feed-text {
    color: var(--white);
    font-size: 16px;
    font-weight: var(--fw-regular);
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
}

.feed-backdrop .feed-text a {
    color: var(--white);
    text-decoration: none;
}

.feed-backdrop .feed-text a:hover {
    color: var(--text-link-hover);
}

.feed-backdrop .feed-time {
    color: rgba(255, 255, 255, 0.8);
    font-size: 14px;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5);
    margin: 0;
}

/* Feed Ratings wie auf Media Card */
.feed-ratings {
    display: flex;
    gap: var(--spacing-8);
    margin-top: var(--spacing-8);
}

.feed-ratings .rating-circle {
    position: relative;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 14px;
    font-weight: var(--fw-bold);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}

/* TMDB-Rating-Background/Color kommt vom zentralen .rating-tmdb-Selektor. */

.feed-ratings .rating-circle.user {
    background: var(--accent-red);
    color: var(--white);
}

/* Responsive Design */
@media (max-width: 768px) {
    .feed-backdrop {
        height: 150px;
    }
    
    .feed-backdrop-content {
        gap: var(--spacing-12);
        padding: var(--spacing-12);
    }
    
    .feed-backdrop .feed-avatar img {
        width: 40px;
        height: 40px;
    }
    
    .feed-backdrop .feed-text {
        font-size: 15px;
    }
    
    .feed-ratings .rating-circle {
        width: 32px;
        height: 32px;
        font-size: 12px;
    }
}

/* Feed Backdrop */
.feed-backdrop {
    width: 100%;
    min-height: 180px;
    border-radius: var(--radius-md) var(--radius-md) 0 0;
    overflow: hidden;
    position: relative;
}

.feed-backdrop img {
    width: 100%;
    min-height: 150px;
    object-fit: cover;
}

/* Gradient Overlay für bessere Lesbarkeit */
/* .feed-backdrop::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    height: 40px;
    background: linear-gradient(transparent, rgba(0,0,0,0.3));
    pointer-events: none;
} */

/* Responsive */
@media (max-width: 768px) {
    .feed-backdrop {
        height: 100px;
    }
}

/* Reaction Info Popup („Wer hat reagiert“) — gleiche Flaeche wie der
   Reaction-Picker (Redesign 2026-10-16).
   z-index muss ueber der Content-Modal-Overlay (100000000) liegen,
   damit Reaktions-Details auch im Review-Reader/Notif-Detail-Modal
   sichtbar sind (Bug 2026-08-28). */
.reaction-info-popup {
    position: fixed;
    z-index: 100000001;
    box-sizing: border-box;
    width: min(280px, calc(100vw - 24px));
    background: var(--background-light);
    border: var(--border-light);
    border-radius: var(--radius-xl);
    box-shadow: var(--shadow-lg);
    animation: reactionPopupFadeIn 0.16s ease-out;
}

@keyframes reactionPopupFadeIn {
    from { opacity: 0; transform: scale(0.94); }
    to   { opacity: 1; transform: scale(1); }
}

.reaction-info-content {
    padding: var(--spacing-8);
    display: flex;
    flex-direction: column;
    gap: var(--spacing-4);
}

.reaction-info-header {
    display: flex;
    align-items: center;
    gap: var(--spacing-8);
    padding: 2px 2px var(--spacing-8) 6px;
    border-bottom: var(--border-light);
}

.reaction-emoji {
    font-size: 22px;
    line-height: 1;
}

.reaction-info-count {
    font-size: var(--font-size-sm);
    color: var(--text-sub);
}

.reaction-info-close {
    margin-left: auto;
    flex: none;
    width: 28px;
    height: 28px;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--text-sub);
    font-size: 16px;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background-color 0.15s ease;
}

.reaction-info-close:hover {
    background: var(--background-hover);
    color: var(--text);
}

.reaction-info-users {
    max-height: 200px;
    overflow-y: auto;
    overscroll-behavior: contain;
}

.reaction-user,
.reaction-username {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--spacing-8);
    min-height: 36px;
    padding: 0 6px;
    border-radius: var(--radius-md);
    font-size: var(--font-size-sm);
    color: var(--text);
    overflow-wrap: anywhere;
}

.reaction-user.current-user {
    background: color-mix(in srgb, var(--primary-color) 12%, transparent);
    font-weight: var(--fw-bold);
}

/* „Entfernen“ neben dem eigenen Namen */
.remove-reaction-inline {
    flex: none;
    height: 25px;
    padding: 0 var(--spacing-8);
    border: var(--border-light);
    border-radius: var(--radius-full);
    background: var(--background);
    color: var(--text-sub);
    font-family: inherit;
    font-size: var(--font-size-xs);
    font-weight: var(--fw-regular);
    cursor: pointer;
}

.remove-reaction-inline:hover {
    color: var(--text);
    border-color: var(--text-inactive);
}

/* „Mit 👍 reagieren“ — wenn man selbst noch nicht so reagiert hat */
.add-reaction-header {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: 32px;
    margin-top: var(--spacing-4);
    padding: 0 var(--spacing-12);
    border: 1px solid var(--primary-color);
    border-radius: var(--radius-full);
    background: color-mix(in srgb, var(--primary-color) 18%, transparent);
    color: var(--text);
    font-family: inherit;
    font-size: var(--font-size-sm);
    cursor: pointer;
    transition: background-color 0.15s ease;
}

.add-reaction-header:hover {
    background: color-mix(in srgb, var(--primary-color) 28%, transparent);
}

@media (prefers-reduced-motion: reduce) {
    .reaction-info-popup {
        animation: none;
    }
}

/* Mobile Tap Indicator */
.reaction-button.mobile-tappable {
    position: relative;
    color: var(--text);
}

.reaction-button.mobile-tappable::after {
    content: '';
    position: absolute;
    top: -2px;
    right: -2px;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--primary-color);
    opacity: 0.7;
    animation: mobileTapPulse 2s infinite;
}

/* Compact feed card with right-side poster */
.feed-item .feed-backdrop {
    display: none !important;
}

.feed-context-menu {
    top: 12px !important;
    right: 12px !important;
}

/* Groessen-Override entfernt 2026-10-02: Der Knopf soll exakt aussehen wie
   auf der Media-Card (36px, Blur, siehe .menu-toggle in components.css).
   Die 32px hier haben ihn kleiner gemacht als ueberall sonst. */

.feed-context-menu .media-menu {
    right: 0;
}

.feed-main {
    display: flex;
    flex-direction: column;
}

.feed-main-top {
    display: flex;
    align-items: flex-start;
}

.feed-main-content {
    flex: 1;
    min-width: 0;
}

.feed-poster-link {
    width: 80px;
    flex-shrink: 0;
    display: block;
    overflow: hidden;
    aspect-ratio: 2 / 3;
    border-radius: var(--spacing-8);
    margin: var(--spacing-16) var(--spacing-16) var(--spacing-8) 0;
}

.feed-poster {
    width: 100%;
    height: 100%;
    display: block;
    object-fit: cover;
}



@media (max-width: 768px) {
    .feed-poster-link {
        width: 68px;
    }
}

@keyframes mobileTapPulse {
    0%, 100% {
        transform: scale(1);
        opacity: 0.7;
    }
    50% {
        transform: scale(1.2);
        opacity: 0.3;
    }
}

/* Responsive Anpassungen */
@media (max-width: 768px) {
    .reaction-button.mobile-tappable::after {
        display: none; /* Verstecke Indikator nach erstem Tap */
    }
    
    .reaction-button:active {
        transform: scale(0.95);
        transition: transform 0.1s;
    }

}

/* --- Feed Review Block --- */
/* Sitzt als direktes Kind von .feed-main, auf voller Breite */
.feed-review-block {
    margin: 0 var(--spacing-16);
    padding: var(--spacing-8) var(--spacing-12);
    border-left: 3px solid var(--sky-blue);
}

.feed-review-text {
    font-size: var(--font-size-base);
    color: var(--text);
    line-height: 1.5;
    word-break: break-word;
    /* Zeilenumbrueche (<br>) und Absaetze (<p class="review-p">) kommen
       fertig aus renderReviewText(); Abstand: --review-para-gap. */
}

.feed-spoiler-hint {
    display: flex;
    align-items: center;
    gap: var(--spacing-8);
    font-size: var(--font-size-base);
    line-height: 1.6;
    color: var(--text-sub);
}

.feed-spoiler-reveal-btn {
    background: none;
    border: none;
    color: var(--text-link);
    font-size: var(--font-size-base);
    cursor: pointer;
    padding: 0;
    text-decoration: underline;
}

.feed-spoiler-reveal-btn:hover {
    color: var(--text-link-hover);
}

.feed-review-block .spoiler-hidden {
    display: none;
}

.feed-review-block.spoiler-revealed .spoiler-hidden {
    display: block;
}

.feed-review-block.spoiler-revealed .feed-spoiler-hint {
    display: none;
}

.feed-review-readmore {
    display: inline-block;
    margin-top: var(--spacing-4);
    background: none;
    border: none;
    color: var(--text-link);
    font-size: var(--font-size-base);
    cursor: pointer;
    padding: 0;
    text-decoration: none;
}

.feed-review-readmore:hover {
    color: var(--text-link-hover);
}

.feed-review-full {
    display: none !important;
}

.feed-review-block.review-expanded > .feed-review-text:not(.feed-review-full) {
    display: none;
}

.feed-review-block.review-expanded .feed-review-full {
    display: block !important;
}

.feed-review-block.review-expanded .feed-review-readmore {
    display: none !important;
}

/* Review activity color */
[data-activity="review"] .feed-body::before {
    background-color: var(--sky-blue);
}

/* Entfernt 2026-10-02 (Feed-Redesign): Cards mit Review hatten das Poster
   per float:right rechts und .feed-main auf display:block. Das war der
   Grund, warum das Poster "mal links, mal rechts" stand — die Regel hat
   das neue Flex-Layout ueberschrieben.
   Das Poster steht jetzt IMMER links, siehe .feed-main--poster. */


/* ==================================================================
   FEED-REDESIGN — BLOCK A (2026-10-02)
   Grundgeruest der Card: Poster links, Titel oben, Zeilen darunter,
   Footer mit Zeit links und unseren bestehenden Buttons rechts.

   Siehe docs/FEED_REDESIGN_PLAN.md Teil 2b (Ziel-Markup).
   Es gelten UNSERE Tokens — die Farben aus dem Entwurf sind Platzhalter.
   ================================================================== */

/* --- Poster: anteilig statt fest ---------------------------------
   Entwurf: 105px bei 358px Cardbreite = 29,3%. Der Feed-Container ist
   auf 600px gedeckelt, 29% ergeben dort ~176px — daher max-width 180px.
   Die alte Umschaltung (klein rechts / gross links je nach Review)
   ist entfallen, das Poster steht jetzt immer links. */
.feed-main--poster {
    display: flex;
    flex-direction: row;
    gap: var(--spacing-16);
    padding: var(--spacing-16) var(--spacing-16) var(--spacing-12);
    align-items: flex-start;
}

/* Die Breite sitzt am Wrapper (.feed-poster-wrap), nicht mehr am Link —
   der Wrapper traegt auch das Kontext-Menue. */
.feed-main--poster .feed-poster-link {
    margin: 0;
    aspect-ratio: 2 / 3;
    border-radius: var(--radius-md);
    overflow: hidden;
    position: relative;
}

.feed-main--poster .feed-main-top {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
}

/* .feed-header traegt bei Zeilen-Cards keinen Avatar mehr — der Platz
   gehoert komplett dem Inhalt. */
.feed-main--rows .feed-header {
    padding: 0;
    gap: 0;
    display: block;
}

/* Satz-Cards MIT Poster (interest, list_item_added): Avatar + Satz
   stehen weiter nebeneinander, nur ohne das alte Innenabstand-Polster —
   das liefert jetzt .feed-main--poster. */
.feed-main--poster:not(.feed-main--rows) .feed-header {
    padding: 0;
}

/* --- Kopfzeile: Titel + Kino-Badge -------------------------------- */
.feed-card-head {
    display: flex;
    flex-wrap: wrap;          /* Badge rutscht unter den Titel wenn eng */
    align-items: baseline;
    gap: var(--spacing-8);
    margin-bottom: var(--spacing-12);
}

a.feed-card-title,
a.feed-card-title:visited {
    font-weight: var(--fw-bold);
    font-size: var(--font-size-lg);
    color: var(--text);
    text-decoration: none;
    line-height: 1.25;
    min-width: 0;
}

a.feed-card-title:hover {
    color: var(--text-link);
}

/* Kino-Badge: bestehende .row-pill, nur nicht schrumpfen lassen. */
.feed-badge-cinema {
    flex-shrink: 0;
}

/* --- Personen- und Ebenen-Zeilen ---------------------------------- */
.feed-rows {
    display: flex;
    flex-direction: column;
}

.feed-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--spacing-8);
    padding: var(--spacing-8) 0;
    border-bottom: var(--border-light);
    min-height: 40px;
}

.feed-row:last-child {
    border-bottom: none;
}

/* flex:1 1 auto + min-width:0 ist entscheidend: Ohne die explizite
   flex-basis:auto bleibt der Link bei langen Namen auf seiner Inhaltsbreite
   stehen und das Badge rutscht direkt hinter den Namen, statt rechts zu
   stehen. Das war der Grund, warum die Badges "mal rechts, mal hinter dem
   Namen" standen. */
a.feed-row-user,
a.feed-row-user:visited,
span.feed-row-user { /* span: Gaeste auf geteilten Reviews (guest_unlink_profiles) */
    display: flex;
    align-items: center;
    gap: var(--spacing-8);
    text-decoration: none;
    color: var(--text);
    min-width: 0;
    flex: 1 1 auto;
}

a.feed-row-user:hover .feed-row-label {
    color: var(--text-link);
}

/* 32px statt 24px (Owner-Wunsch 04.10.): die Bilder waren zu klein, um
   die Person zu erkennen. Gilt ueber feed.css fuer alle Zeilen-Cards —
   Feed, Notification-Modal und die uebrigen Modale nutzen denselben
   Renderer, es gibt also nur diese eine Stelle. */
.feed-row-avatar-wrap {
    position: relative;
    flex-shrink: 0;
    width: 32px;
    height: 32px;
}

.feed-row-avatar {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    object-fit: cover;
    display: block;
}

.feed-row-label {
    font-size: var(--font-size-sm);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

/* Rechts in der Zeile steht IMMER genau ein Element (Plan G3):
   Wertung schlaegt "Gesehen", Kino gehoert in die Titelzeile. */
/* margin-left:auto drueckt das Element zuverlaessig an den rechten Rand —
   unabhaengig davon, wie breit der Link davor ausfaellt. */
/* 32px wie der Avatar links in derselben Zeile (Owner-Wunsch 04.10.).
   Vorher 24px — neben dem auf 32px vergroesserten Avatar wirkte die
   Zeile dadurch unsymmetrisch.

   Die Schrift kann mit: bei 24px waren nur 11px moeglich, also unter der
   Untergrenze von DESIGN_GUIDE R-9. Im 32px-Kreis passen 12px, womit
   die Ausnahme entfaellt. "10.0" ist der breiteste Wert und passt. */
.feed-row-rating.rating-circle {
    position: relative;
    width: 32px;
    height: 32px;
    font-size: 12px;
    flex-shrink: 0;
    margin-left: auto;
}

.feed-row-pill {
    flex-shrink: 0;
    margin-left: auto;
    /* Gleiche Hoehe wie die Wertungs-Kreise daneben (32px, Owner 18.10.):
       alle Badges im Feed gleich gross. */
    height: 32px;
    padding: 0 var(--spacing-12);
}

/* --- Verbindungs-Icon zwischen gemeinsam Sehenden (05.10.) ----------
   Owner-Wunsch: zwischen den Profilbildern einer geteilten Sichtung ein
   ph-link-Icon, mittig in der Avatar-Spalte auf der Trennlinie.

   Streng ueberlagernd: position:absolute nimmt das Icon aus dem Fluss,
   die Zeile bekommt KEIN zusaetzliches Padding und keine groessere
   min-height. Die Abstaende der vorhandenen Elemente bleiben damit
   unveraendert — darauf hat der Owner ausdruecklich hingewiesen.

   .feed-row--linked sitzt an der UNTEREN Zeile einer Verbindung; das
   Icon wird an deren Oberkante zentriert (top:0 + translateY(-50%)),
   also genau auf die Trennlinie der Zeile darueber.

   Welche Zeilen die Klasse bekommen, entscheidet
   feed_render_person_rows_html() in includes/feed-renderer.php — nur
   echte Mitseher, nie die angehaengte eigene Wertung
   (.feed-row--own-rating).

   16px: dieselbe Groesse wie das Highlight-Badge darunter, damit die
   Spalte ruhig bleibt. Mitte der 32px-Avatarspalte ist left:16px. */
.feed-row--linked::before {
    content: "\e2e2";
    font-family: 'Phosphor';
    font-weight: var(--fw-regular);
    font-style: normal;
    line-height: 1;
    -webkit-font-smoothing: antialiased;
    position: absolute;
    /* Mittig ueber die ganze Zeilenbreite (Owner-Variante 05.10.).
       Die Alternative — mittig in der 32px-Avatarspalte, also left:16px —
       steht im Verlauf; umschalten ist ein Einzeiler. */
    left: 50%;
    top: 0;
    transform: translate(-50%, -50%);
    width: 22px;
    height: 22px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 12px;
    /* Markenfarben statt gedecktem Grau (Owner-Wunsch 05.10.). Dieselbe
       Kombination wie .suggestion-bookmark und .tab-badge in main.css:
       --sky-blue ist ein fester Markenwert (kein Theme-Wechsel),
       --text-darker ist pro Theme definiert und bleibt darauf lesbar.
       Der gefuellte Kreis stanzt zugleich die Trennlinie aus. */
    background: var(--sky-blue);
    color: var(--text-darker);
    border-radius: 50%;
    pointer-events: none;
    z-index: 1;
}

/* Bezugspunkt fuer das absolut positionierte Icon. Nur position, keine
   Masse — sonst verschieben sich die Zeilen. */
.feed-row {
    position: relative;
}

/* Highlight-Badge an der Zeile: dieselbe Komponente wie am grossen
   Avatar, nur auf 16px verkleinert (Plan G4). */
.feed-row.is-highlighted .feed-row-avatar-wrap::after {
    content: "\ecfa";
    font-family: 'Phosphor';
    font-weight: var(--fw-regular);
    font-style: normal;
    line-height: 1;
    -webkit-font-smoothing: antialiased;
    position: absolute;
    right: -4px;
    bottom: -4px;
    width: 16px;
    height: 16px;
    background: var(--accent-red);
    color: var(--white);
    border-radius: 50%;
    border: 2px solid var(--background-light);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 9px;    /* Icon im 16px-Kreis, geometrisch begrenzt */
    pointer-events: none;
}

/* --- Footer: Zeit links, unsere Buttons rechts -------------------- */
.feed-footer {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--spacing-8);
    padding: var(--spacing-8) var(--spacing-16) var(--spacing-12);
    border-top: var(--border-light);
}

/* align-self:flex-start haelt die Zeit oben, wenn die Reactions daneben
   auf mehrere Zeilen umbrechen — sonst wuerde sie mittig zur gewachsenen
   Hoehe stehen. */
.feed-footer .feed-time {
    font-size: var(--font-size-xs);
    color: var(--text-sub);
    flex-shrink: 0;
    align-self: flex-start;
    padding-top: var(--spacing-4);
}

/* Die Buttons selbst bleiben unveraendert (Vorgabe) — hier wird nur
   ihre Position festgelegt. */
/* Viele Reactions duerfen umbrechen, ohne die Zeitangabe zu verdraengen.
   flex:1 1 auto + min-width:0 laesst den Block schrumpfen, flex-wrap
   bricht ihn dann innerhalb seiner Breite um. Die Zeit behaelt ihren
   Platz rechts (flex-shrink:0 dort). */
.feed-footer-actions {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--spacing-8);
    flex: 1 1 auto;
    min-width: 0;
    margin-left: auto;
}

/* Kommentar-Panel laeuft ueber die volle Breite unter der Action-Zeile.
   order:3 ist wichtig: Zeit und Buttons tragen order 2 bzw. 1 — ohne
   eigenen Wert haette das Panel den Standard 0 und waere beim Aufklappen
   VOR die Buttons gerutscht. Die Knopfzeile waere dadurch unter die
   Kommentare gewandert. */
.feed-footer .comments-section {
    order: 3;
    flex-basis: 100%;
    width: 100%;
}

/* --- Review-Block: volle Cardbreite ------------------------------- */
/* Review-Abstaende kommen aus der Basis-Regel .feed-review-block weiter
   oben (margin: 0 var(--spacing-16)). Die fruehere Zusatzregel hier war
   doppelt gemoppelt. */

/* --- Desktop ------------------------------------------------------ */
@media (min-width: 769px) {
    .feed-main--poster {
        gap: var(--spacing-20);
        padding: var(--spacing-20) var(--spacing-20) var(--spacing-16);
    }
    .feed-row {
        min-height: 44px;
    }
    a.feed-card-title {
        font-size: var(--font-size-xl);
    }
}

/* ==================================================================
   FEED-REDESIGN — BLOCK C (2026-10-02)
   Review: Zitat-Optik, Kuerzung per CSS, Lese-Modal statt Ausklappen.
   ================================================================== */

/* Zeilenzahl kommt aus einer Variable, damit sie je Kontext gesetzt
   werden kann (Plan C2): Einzel-Card 5 Zeilen, geteilte Card 2.
   Der Server setzt sie inline via --feed-review-lines. */
.feed-review-block {
    --feed-review-lines: 5;
}

/* :not(.spoiler-hidden) ist entscheidend: Ohne die Einschraenkung setzt
   display:-webkit-box das display:none der Spoiler-Regel ausser Kraft
   (gleiche Spezifitaet, aber spaeter in der Datei) — der Spoiler-Text war
   dadurch trotz Warnung lesbar. */
.feed-review-block .feed-review-text:not(.spoiler-hidden) {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: var(--feed-review-lines);
    line-clamp: var(--feed-review-lines);
    overflow: hidden;
}

/* Namenspraefix bei geteilten Cards ("blanksy:"). */
.feed-review-author {
    font-weight: var(--fw-bold);
}

/* "Weiterlesen" sitzt direkt unter dem Zitat. Es ist immer im Markup —
   ob der Text ueberhaupt gekuerzt ist, weiss nur der Browser. Der Knopf
   ist deshalb dezent gehalten, damit er auch bei kurzen Reviews nicht
   stoert. */
.feed-review-readmore {
    background: none;
    border: none;
    padding: var(--spacing-4) 0 0;
    margin: 0;
    color: var(--text-link);
    font-family: inherit;
    font-size: var(--font-size-sm);
    cursor: pointer;
}

.feed-review-readmore:hover {
    color: var(--text-link-hover);
}

/* Spoiler: solange nicht aufgedeckt, bleibt auch der Knopf weg. */
.feed-review-block .feed-review-readmore.spoiler-hidden {
    display: none;
}
.feed-review-block.spoiler-revealed .feed-review-readmore.spoiler-hidden {
    display: inline-block;
}

/* Das kleine Lese-Modal (.feed-review-modal-*) ist am 03.10. entfallen.
   "Weiterlesen" oeffnet jetzt die vollstaendige Card-Ansicht, und
   innerhalb eines Modals wird der Spoiler an Ort und Stelle aufgedeckt
   — ein Modal ueber dem Modal gibt es nicht mehr. Die zugehoerigen
   Regeln sind mit entfernt (CLAUDE.md: toter Code wird geloescht). */

/* ==================================================================
   FEED-REDESIGN — BLOCK D (2026-10-02)
   Kontext-Menue sitzt auf dem Poster, wie auf der Media-Card.

   Vorher klebte es oben rechts in der Card-Ecke. Dort kollidiert es im
   neuen Layout mit dem Kino-Badge in der Titelzeile.
   ================================================================== */
.feed-main--poster {
    position: relative;
}

/* Das Menue ist im Markup ein GESCHWISTER von .feed-main (steht dahinter
   im .feed-item). Anker fuer die absolute Position ist deshalb
   .feed-item selbst — das traegt bereits position:relative.
   Werte wie auf der Media-Card: 8px aus der Poster-Ecke, dazu das
   Padding von .feed-main--rows (16px). */
/* Der Knopf sitzt auf dem Poster, oben RECHTS — wie auf der Media-Card.
   Optik und Groesse kommen unveraendert aus .menu-toggle (components.css).

   Das Menue steht im Markup weit hinten (es braucht Status-Daten, die
   erst nach dem Footer geladen werden). Statt seine Position aus der
   anteiligen Posterbreite zu rechnen, bekommt .feed-poster-wrap eine
   eigene Ebene und das Menue wird per Flex dorthin einsortiert. */
.feed-poster-wrap {
    position: relative;
    flex-shrink: 0;
    width: 29%;
    min-width: 96px;
    max-width: 180px;
    align-self: flex-start;
}

.feed-poster-wrap .feed-poster-link {
    width: 100%;
    max-width: none;
    min-width: 0;
    margin: 0;
    display: block;
}

/* Das Menue wird aus dem Fluss genommen und ueber dem Poster platziert.
   Anker ist .feed-main--poster; die Breite des Posters steckt in der
   gleichen Variable wie oben, deshalb stimmt die rechte Kante. */
/* Posterbreite als Variable, damit Wrapper und Menue garantiert denselben
   Wert benutzen. Die 29% beziehen sich auf .feed-main--poster (die Card),
   genau wie beim Wrapper — deshalb stimmt die rechte Kante. */
.feed-main--poster {
    --feed-poster-w: clamp(96px, 29%, 180px);
}

/* Das Menue spannt sich ueber die Posterbreite und schiebt den Knopf per
   justify-content an dessen rechte Kante.

   Die Breite muss exakt dem Wrapper entsprechen. Der rechnet 29% von
   .feed-main--poster (Cardbreite minus 2x16px Padding), das Menue haengt
   aber an .feed-item (volle Cardbreite). Deshalb hier derselbe Wert,
   aber auf die um das Padding verringerte Breite bezogen. */
.feed-item:has(.feed-main--poster) .feed-context-menu {
    top: calc(var(--spacing-16) + 8px) !important;
    right: auto !important;
    left: var(--spacing-16);
    width: clamp(96px, calc((100% - 2 * var(--spacing-16)) * 0.29), 180px);
    display: flex;
    justify-content: flex-end;
    padding-right: 8px;
    pointer-events: none;   /* nur der Knopf selbst ist klickbar */
    z-index: 3;
}

.feed-item:has(.feed-main--poster) .feed-context-menu .menu-toggle,
.feed-item:has(.feed-main--poster) .feed-context-menu .media-menu {
    pointer-events: auto;
}

/* Menue-Panel oeffnet nach links, damit es nicht ueber den Cardrand
   hinauslaeuft — der Knopf steht ja mitten in der Card. */
.feed-item:has(.feed-main--poster) .feed-context-menu .media-menu {
    left: auto;
    right: 0;
}

/* ==================================================================
   FEED-REDESIGN — BLOCK E (2026-10-02)
   "Interessiert auch" unter Interest-Cards.
   ================================================================== */
.feed-interest-also {
    margin-top: var(--spacing-12);
}

.feed-interest-also-label {
    font-size: var(--font-size-sm);
    color: var(--text-sub);
    margin-bottom: var(--spacing-4);
}

/* Nutzt dieselben .feed-row-Styles wie die Personen-Zeilen, hat aber
   kein Element rechts — deshalb keine Trennlinie und weniger Hoehe. */
.feed-interest-also .feed-row {
    border-bottom: none;
    min-height: 40px;   /* wie oben: 32px Avatar + 2x4px Padding */
    padding: var(--spacing-4) 0;
}

.feed-row--more .feed-row-label {
    color: var(--text-sub);
    font-size: var(--font-size-sm);
}

/* ==================================================================
   FEED-REDESIGN — BLOCK F (2026-10-02)
   Serien-Sammel-Card: Ebenen-Zeilen statt mehrerer Cards.
   ================================================================== */

/* Ebenen-Zeile: Label links (fett, kein Avatar), Status rechts. */
.feed-row--season {
    justify-content: space-between;
}

.feed-row-label--season {
    font-weight: var(--fw-bold);
    flex: 1;
}


/* ==================================================================
   FEED-REDESIGN — Korrekturen 02.10. (Runde 2)
   ================================================================== */

/* --- Farbcode: eigene Badges sky-blue, fremde champagne -------------
   Gilt in der ganzen App (vgl. .rating-user / .rating-friend). */
.feed-row-pill.is-own {
    background: var(--sky-blue);
    color: var(--text-darker);
}

.feed-row-pill.is-friend {
    background: var(--accent-soft-bg);
    color: var(--accent-soft-text);
}

/* --- Zeilen-Card: Inhalt haengt direkt in .feed-main-top ------------
   Kein .feed-header-Wrapper mehr, damit die Wertungen bis zum rechten
   Cardrand laufen und nicht vorzeitig enden. */
.feed-main--rows .feed-main-top {
    display: block;
    min-width: 0;
}

.feed-main--rows .feed-content--rows {
    width: 100%;
}

/* --- Zeilen-Abstand: war deutlich zu luftig ------------------------ */
/* min-height folgt der Avatargroesse: 32px Bild + 2x4px Padding = 40px.
   Bliebe sie bei 32px, waere sie wirkungslos — die Zeile wuerde ohnehin
   vom Avatar aufgespannt, nur ohne definierte Untergrenze. */
.feed-row {
    padding: var(--spacing-4) 0;
    min-height: 40px;
}

@media (min-width: 769px) {
    .feed-row {
        min-height: 44px;
    }
}

/* --- Footer: Reactions links, Zeit rechts -------------------------- */
.feed-footer .feed-time {
    order: 2;
    margin-left: auto;
}

.feed-footer-actions {
    order: 1;
    margin-left: 0;
    margin-right: auto;
}

/* Spoiler-Regeln stehen bereits weiter oben (.feed-review-block
   .spoiler-hidden { display:none }). Eine zweite Definition hier hat sie
   ueberschrieben — deshalb war der Spoiler-Text trotz Warnung lesbar. */

/* --- Autor-Zeile der Serien-Sammel-Card ---------------------------- */
/* Steht ueber den Ebenen-Zeilen und traegt keine eigene Trennlinie —
   die Ebenen darunter bringen ihre eigene Gliederung mit. */
.feed-rows--author {
    margin-bottom: var(--spacing-4);
}

.feed-row--author {
    border-bottom: none;
}

/* --- Review neben dem Poster (Zeilen-Cards) ------------------------
   Bei Zeilen-Cards steht die Review in .feed-main-top, also rechts neben
   dem Poster. Dort ist genug Platz, und die Card wird kompakter als mit
   der Review unterhalb.

   Die seitlichen Abstaende der Basis-Regel gelten hier nicht — der Block
   sitzt ja schon innerhalb des Card-Paddings. */
.feed-main--rows .feed-main-top .feed-review-block {
    margin: var(--spacing-12) 0 0;
}

/* Unter 480px wird die Spalte neben dem Poster zu schmal fuer Fliesstext.
   Dort rutscht die Review unter das Poster, ueber die volle Breite. */
/* Mobil laeuft die Review ueber die VOLLE Cardbreite, nicht neben dem
   Poster. Grenze ist der Standard-Breakpoint 768px (DESIGN_GUIDE R-3) —
   480 waere ein Sonder-Breakpoint, den die Regel nur im Notfall erlaubt.
   Oberhalb von 600px ist die Card ohnehin gedeckelt, die Spalte neben dem
   Poster bleibt dort konstant bei ~387px.

   Umsetzung ueber order + flex-wrap am .feed-main--poster: Das Review-
   Element sitzt im Markup in .feed-main-top. Damit es darunter landen
   kann, wird .feed-main-top aufgebrochen und die Review als letztes
   Element ueber die volle Breite gezogen. */
@media (max-width: 768px) {
    .feed-main--rows {
        flex-wrap: wrap;
    }

    .feed-main--rows .feed-main-top {
        display: contents;
    }

    /* Poster und Zeilen bleiben nebeneinander … */
    .feed-main--rows .feed-poster-wrap {
        order: 1;
    }
    .feed-main--rows .feed-content--rows {
        order: 2;
        flex: 1;
        min-width: 0;
    }

    /* … die Review rutscht in eine eigene Zeile darunter. */
    .feed-main--rows .feed-review-block {
        order: 3;
        flex-basis: 100%;
        width: 100%;
        margin: var(--spacing-12) 0 0;
    }
}

/* ==================================================================
   Mobile-Feinschliff (02.10., Runde 3)
   ================================================================== */

/* --- B: Name und Badge brauchen auf schmalen Geraeten zwei Zeilen ---
   Bei 375px passen "MoviegefluesterJenny" und "Interessiert" nicht
   nebeneinander — der Name punktete aus. Statt ihn abzuschneiden bricht
   die Zeile jetzt um: Name oben, Badge rechtsbuendig darunter.

   Ab 480px ist genug Platz fuer eine Zeile. */

/* --- E: Kontext-Knopf mobil kleiner -------------------------------
   36px nehmen auf einem 96px breiten Poster zu viel Raum ein. 24px
   reichen; die Trefferflaeche bleibt durch das ::after-Padding gross
   genug (DESIGN_GUIDE: min. 44px). */
@media (max-width: 768px) {
    .feed-item:has(.feed-main--poster) .feed-context-menu .menu-toggle {
        width: 24px;
        height: 24px;
        font-size: 12px;
        position: relative;
    }

    .feed-item:has(.feed-main--poster) .feed-context-menu .menu-toggle::after {
        content: "";
        position: absolute;
        inset: -10px;   /* 24 + 2x10 = 44px Trefferflaeche */
    }

    /* Knopf dichter an die Poster-Ecke: weiter nach oben und etwas weiter
       nach links. Bei 24px Knopfgroesse wirkten 6px Abstand zu viel. */
    .feed-item:has(.feed-main--poster) .feed-context-menu {
        top: calc(var(--spacing-16) + 2px) !important;
        padding-right: 2px;
    }
}

/* --- Kontext-Knopf zurueck in die Card-Ecke (23.10.) ---------------
   Im Feed und im Community-Feed sitzt der Knopf wieder oben rechts in
   der Card statt auf dem Poster (Owner-Wunsch). Nur innerhalb von
   .feed-container: im Benachrichtigungs-Modal steht oben rechts das X,
   dort bleibt der Knopf auf dem Poster (Regeln oben + notifications.css).

   Knopf und Wertungs-Kreise stehen auf einer Linie: Der Knopf ist 32px
   wie die Kreise, und top/right entsprechen dem Card-Padding — damit
   endet er an derselben rechten Kante wie die Wertungen.
   Mobil: Padding rundum 12px. Desktop: rundum 16px.

   Damit der Titel nicht unter den Knopf laeuft, bekommt die erste Zeile
   rechts 40px Platz (Knopf 32px + 8px Luft). */
.feed-container .feed-main--poster {
    padding: var(--spacing-12);
}

.feed-container .feed-item:has(.feed-main--poster) .feed-context-menu {
    top: var(--spacing-12) !important;
    right: var(--spacing-12) !important;
    left: auto;
    width: auto;
    padding-right: 0;
}

/* Auf dem Poster traegt der halbtransparente Blur-Hintergrund aus
   components.css, auf der dunklen Card verschwindet er. Deshalb hier eine
   feste Flaeche. Im Light-Theme ist --background-light so weiss wie die
   Card — dort das naechste Grau, sonst waere der Knopf unsichtbar. */
.feed-container .feed-item:has(.feed-main--poster) .feed-context-menu .menu-toggle {
    width: 32px;
    height: 32px;
    font-size: 14px;
    background: var(--background-light);
    color: var(--text);
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}

.feed-container .feed-item:has(.feed-main--poster) .feed-context-menu .menu-toggle:hover {
    background: var(--background-hover);
}

:root[data-theme="light"] .feed-container .feed-item:has(.feed-main--poster) .feed-context-menu .menu-toggle,
:root[data-theme="light"] .feed-container .feed-item:has(.feed-main--poster) .feed-context-menu .menu-toggle:hover {
    background: var(--background-active);
}

@media (max-width: 768px) {
    .feed-container .feed-item:has(.feed-main--poster) .feed-context-menu {
        top: var(--spacing-8) !important;
    }
}

.feed-container .feed-main--poster .feed-card-head,
.feed-container .feed-main--poster .feed-content > .feed-text:first-child {
    padding-right: var(--spacing-40);
}

@media (min-width: 769px) {
    .feed-container .feed-main--poster {
        padding: var(--spacing-16);
    }

    .feed-container .feed-item:has(.feed-main--poster) .feed-context-menu {
        top: var(--spacing-16) !important;
        right: var(--spacing-16) !important;
    }
}

/* ==================================================================
   Korrekturen 02.10. — Runde 4
   ================================================================== */



/* ==================================================================
   Korrekturen 02.10. — Runde 5
   ================================================================== */

/* --- Reviews gemeinsamer Sichtungen -------------------------------
   Stehen als eigener Block UNTER der zweispaltigen Zone (Poster + Zeilen)
   und laufen damit ueber die volle Cardbreite — in jeder Breite, auch am
   Desktop. Die seitlichen Abstaende kommen aus .feed-review-block. */
/* Satz-Cards (Schatten-Cards, "X hat eine Review geschrieben"):
   Ihre Review steht im Markup AUSSERHALB von .feed-main, direkt vor dem
   Footer — dort greift dessen Padding nicht. Ohne diese Regel klebte sie
   an der Footer-Trennlinie und begann buendig am Cardrand, waehrend sie
   bei allen anderen Cards eingerueckt steht (Owner-Meldung 05.10.,
   "Nur fuer dein Leben").

   Dieselben Werte wie bei .feed-reviews-group darunter. */
.feed-item:has(.feed-main--poster:not(.feed-main--rows)) > .feed-review-block {
    margin-top: var(--spacing-12);
    margin-bottom: var(--spacing-12);
}

.feed-reviews-group {
    margin-top: var(--spacing-12);
    /* Abstand zum Footer (05.10.): Die Gruppe steht direkt vor
       .feed-footer und hatte nur margin-top — die Review schloss
       buendig an der Trennlinie ab. Bei allen anderen Cards liefert
       .feed-main--poster unten 12px, bevor der Footer beginnt; hier
       derselbe Wert, damit der Abstand ueberall gleich aussieht. */
    margin-bottom: var(--spacing-12);
}

.feed-reviews-group .feed-review-block + .feed-review-block {
    margin-top: var(--spacing-8);
}

/* --- Pille: Text einklappen NUR wenn der Platz nicht reicht --------
   Die Pille darf schrumpfen, bis nur noch das Icon uebrig ist. Dann wird
   sie zum 32px-Kreis, so gross wie die Wertungs-Kreise daneben (bis
   18.10. 24px — wirkte neben den 32px-Wertungen zu klein).

   Umsetzung ohne Breakpoint: Der Text bekommt eine maximale Breite von
   0 nur dann, wenn die Zeile zu eng wird — das laesst sich in CSS nicht
   messen. Deshalb der pragmatische Weg: Die Pille darf schrumpfen
   (min-width:0, Text mit overflow:hidden), und ab der Groesse eines
   Kreises kippt sie in die runde Form.

   Der Name punktet weiterhin aus (white-space:nowrap bleibt). */
.feed-row-pill {
    min-width: 32px;
    max-width: 100%;
    overflow: hidden;
}

.feed-row-pill .feed-pill-text {
    overflow: hidden;
    text-overflow: clip;
    white-space: nowrap;
}

/* Sehr schmale Zeilen: Pille auf Icon reduzieren und rund machen.
   container queries waeren sauberer, haben aber im iOS-Container
   (PWABuilder) keine verlaessliche Unterstuetzung — deshalb eine
   Breiten-Regel, die nur dort greift wo es wirklich eng wird. */
@media (max-width: 420px) {
    .feed-row-pill {
        width: 32px;
        height: 32px;
        padding: 0;
        border-radius: 50%;
        justify-content: center;
        flex-shrink: 0;
    }

    .feed-row-pill .feed-pill-text {
        display: none;
    }

    .feed-row-pill i {
        margin: 0;
        font-size: 16px;
    }

    /* Tipp zeigt den Text als Blase (feed-pill-tip.js). */
    .feed-row-pill {
        cursor: pointer;
    }
}

/* --- Blase fuer eingeklappte Pillen (feed-pill-tip.js, 23.10.) -------
   Form und Groesse wie die Onboarding-Blase .ux-coach (main.css), Farbe
   wie die Pille: eigene sky-blue, fremde champagne. */
.feed-pill-tip {
    position: fixed;
    z-index: calc(var(--z-modal) - 1);
    font-size: var(--font-size-xs);
    font-weight: var(--fw-bold);
    line-height: 1.35;
    padding: var(--spacing-8) var(--spacing-12);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    pointer-events: none;
    width: max-content;
    max-width: 240px;
    --feed-pill-tip-bg: var(--accent-soft-bg);
    background: var(--feed-pill-tip-bg);
    color: var(--accent-soft-text);
}

.feed-pill-tip.is-own {
    --feed-pill-tip-bg: var(--sky-blue);
    color: var(--text-darker);
}

.feed-pill-tip[hidden] {
    display: none;
}

.feed-pill-tip::after {
    content: '';
    position: absolute;
    border: 6px solid transparent;
}

.feed-pill-tip[data-side="left"]::after {
    left: 100%;
    top: 50%;
    transform: translateY(-50%);
    border-left-color: var(--feed-pill-tip-bg);
}

.feed-pill-tip[data-side="above"]::after,
.feed-pill-tip[data-side="below"]::after {
    left: var(--feed-pill-tip-arrow-x, 50%);
    transform: translateX(-50%);
}

.feed-pill-tip[data-side="above"]::after {
    top: 100%;
    border-top-color: var(--feed-pill-tip-bg);
}

.feed-pill-tip[data-side="below"]::after {
    bottom: 100%;
    border-bottom-color: var(--feed-pill-tip-bg);
}

/* ==================================================================
   Listen-Modal + Mehr-Knopf (02.10.2026)

   Drei Faelle teilen sich dieselbe Mechanik: viele Staffeln, viele
   Interessenten, viele Beteiligte an einer gemeinsamen Sichtung.
   Die vollstaendige Liste steht versteckt im Markup und wird vom Modal
   uebernommen — kein Nachladen.
   ================================================================== */

/* Der Mehr-Knopf sieht aus wie eine Zeile, ist aber ein Button. */
.feed-rows-more-btn {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    gap: var(--spacing-8);
    background: none;
    border: none;
    border-bottom: none;
    padding: var(--spacing-8) 0;
    font-family: inherit;
    font-size: var(--font-size-sm);
    color: var(--text-link);
    cursor: pointer;
    text-align: left;
}

.feed-rows-more-btn:hover .feed-row-label {
    color: var(--text-link-hover);
}

.feed-rows-more-btn i {
    flex-shrink: 0;
    font-size: 14px;
}

.feed-rows-more-btn .feed-row-label {
    color: var(--text-link);
}

/* Versteckte Vollfassung: nur Datenquelle fuers Modal. */
.feed-rows--full {
    display: none;
}

/* Der Knopf steht zwischen den Review-Bloecken und muss deren Einrueckung
   uebernehmen: 16px Aussenabstand (margin der Bloecke) plus 12px Padding
   plus 3px Zitatstrich — sonst klebt er am linken Cardrand, waehrend die
   Reviews darueber eingerueckt sind. */
.feed-reviews-overflow {
    margin: var(--spacing-8) var(--spacing-16) 0;
    padding-left: calc(var(--spacing-12) + 3px);
}

/* --- Das Modal ----------------------------------------------------- */
.feed-list-modal-body {
    padding: var(--spacing-24);
}

/* padding-right: Platz fuer das X oben rechts (8px + 36px, Body hat 24px). */
.feed-list-modal-title,
.feed-list-modal-subtitle:first-child {
    padding-right: var(--spacing-24);
}

.feed-list-modal-title {
    font-size: var(--font-size-lg);
    font-weight: var(--fw-bold);
    color: var(--text);
    margin: 0;
}

.feed-list-modal-subtitle {
    font-size: var(--font-size-sm);
    color: var(--text-sub);
    margin: var(--spacing-4) 0 var(--spacing-16);
}

/* Die Zeilen bringen ihre Styles aus .feed-row mit. Im Modal ist mehr
   Platz, deshalb duerfen die Pillen hier immer ihren Text zeigen. */
.feed-list-modal-rows .feed-row {
    border-bottom: var(--border-light);
}

.feed-list-modal-rows .feed-row:last-child {
    border-bottom: none;
}

.feed-list-modal-rows .feed-row-pill {
    width: auto;
    height: 32px;
    padding: 0 var(--spacing-12);
    border-radius: var(--radius-full);
}

.feed-list-modal-rows .feed-row-pill .feed-pill-text {
    display: inline;
}

/* Reviews im Modal ohne seitlichen Aussenabstand — das Modal hat eigenes
   Padding. */
.feed-list-modal-rows .feed-review-block {
    margin-left: 0;
    margin-right: 0;
}
