/*
 * Quick-pass stylesheet for the eGun PWA (mobile-first - this replaces
 * m.egun.de). Palette is taken from the legacy desktop theme
 * (egun-src/auc_style.css: #2519bc = "tpl_color1", #ffcc33 = "tpl_color2")
 * so the new app reads as the same brand, not a redesign - no legacy CSS
 * was copied, only the color values.
 */

/* eGun Display: Barlow Semi Condensed 600 (OFL, self-hosted - see
   assets/fonts/LICENSE.txt). The condensed industrial grotesque of German
   tool/arms catalogs - carries headlines, prices and the countdown, while
   body text stays on the system stack. Latin + latin-ext subsets only
   (38 KB total): Greek/Cyrillic UI text (el/bg locales) falls back to the
   system stack's bold, digits are latin so PRICES render in the display
   face in every locale. font-display: swap - text is never invisible. */
@font-face {
    font-family: 'eGun Display';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url("../fonts/barlow-semicondensed-600-latin-BwiUhEJ.woff2") format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
    font-family: 'eGun Display';
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url("../fonts/barlow-semicondensed-600-latin-ext-SElm7fV.woff2") format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
    --font-display: 'eGun Display', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    /* Controls sit a step squarer than cards - print-catalog, not bubble. */
    --radius-control: 4px;
    --egun-blue: #2519bc;
    --egun-blue-dark: #1a1288;
    --egun-gold: #ffcc33;
    --egun-red: #c00000;
    /* The wordmark's fourth letter color (sampled from egun-logo.png's
       "n") - completes the brand set red/gold/blue/green used by the
       dashboard's world-coding dots and the all-clear check. */
    --egun-green: #009030;
    --egun-text: #1a1a1a;
    --egun-text-muted: #666;
    --egun-border: #ddd;
    --egun-bg: #f5f5f7;
    --egun-surface: #fff;
    --radius: 8px;
}

* {
    box-sizing: border-box;
}

/* Brand focus ring (design audit #10): one blue ring everywhere instead
   of each browser's default black/dotted outline. Only :focus-visible -
   pointer taps stay ring-free. */
:focus-visible {
    outline: 2px solid var(--egun-blue);
    outline-offset: 2px;
}

/* The UA's own `[hidden] { display: none }` loses to any author-set
   `display` (e.g. .btn-quiet's inline-block), which silently broke the
   show-once toggle buttons (Notiz, Beschreibung ergänzen) staying visible
   after being clicked-and-hidden via JS. Standard reset guard. */
[hidden] {
    display: none !important;
}

body {
    margin: 0;
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    color: var(--egun-text);
    background: var(--egun-bg);
    line-height: 1.4;
    /* Safety net against oversized content (chiefly raw seller-authored
       HTML in .auction-description, which has its own local overflow
       handling below) forcing the whole page to scroll sideways. */
    overflow-x: hidden;
}

a {
    color: var(--egun-blue);
    text-decoration: none;
}

a:hover {
    text-decoration: underline;
}

h1, h2 {
    line-height: 1.2;
}

/* Katalog & Kerbe phase 2: headlines in the display face - the condensed
   catalog voice carries every section title; body text stays system. */
h1, h2, h3, legend {
    font-family: var(--font-display);
    font-weight: 600;
    letter-spacing: 0.01em;
}

/* Fieldset legends are eyebrows EVERYWHERE (audit #5 - preferences and
   registration had plain bold legends while the sell form already used
   the quiet uppercase device; the sell form's red world dot stays its
   own rule). */
legend {
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.09em;
    color: var(--egun-text-muted);
}

/* Full-width primary page action (audit #3: "Anmelden"/"Registrieren"/
   "Speichern" were small left-aligned buttons while other pages' primary
   CTAs are blocks - one policy now). */
.btn-block {
    display: block;
    width: 100%;
}


/* --- Header --- */

.site-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.75rem 1rem;
    background: var(--egun-surface);
    color: var(--egun-blue);
    border-bottom: 1px solid var(--egun-border);
    position: sticky;
    top: 0;
    z-index: 10;
}

.site-header__brand {
    display: flex;
    align-items: center;
    text-decoration: none;
}

/* Flag language switcher between the logo and the ad banner: the flag
   summary shows the CURRENT language; the panel lists all 23 as
   flag + native name. margin-right:auto (moved here from __brand) keeps
   logo+flag as the left cluster and pushes banner/nick/burger right. */
.site-header__lang {
    position: relative;
    margin-right: auto;
}

.site-header__lang summary {
    display: flex;
    align-items: center;
    list-style: none;
    cursor: pointer;
    line-height: 1;
    padding: 0.25rem 0.3rem;
    border-radius: 4px;
    user-select: none;
}

/* Inline-SVG flags (symbols in _lang-switcher.html.twig). The 1px ring
   keeps flags with white edges (PL, FI, ...) visible on the white
   header/panel surface. */
.site-header__lang-flag {
    display: block;
    width: 24px;
    height: 16px;
    border-radius: 2px;
    box-shadow: 0 0 0 1px var(--egun-border);
    flex: none;
}

.site-header__lang-flag--small {
    width: 21px;
    height: 14px;
}

.site-header__lang summary::-webkit-details-marker {
    display: none;
}

.site-header__lang[open] summary {
    background: var(--egun-bg);
}

.site-header__lang-panel {
    position: absolute;
    left: 0;
    top: calc(100% + 6px);
    z-index: 20;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 2px;
    width: max-content;
    max-width: calc(100vw - 2rem);
    max-height: 70vh;
    overflow-y: auto;
    padding: 0.4rem;
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    box-shadow: 0 4px 14px rgb(0 0 0 / 0.15);
}

.site-header__lang-panel a {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.3rem 0.5rem;
    border-radius: 4px;
    font-size: 0.85rem;
    color: inherit;
    white-space: nowrap;
}

.site-header__lang-panel a:hover {
    background: var(--egun-bg);
    text-decoration: none;
}

.site-header__lang-panel a[aria-current="true"] {
    font-weight: 700;
    background: var(--egun-bg);
}

/* The real multicolor eGun wordmark (assets copied from the legacy site,
   gfx-app2/Logo.png + the ® from images/logo.gif) - sits directly on the
   white header, matching the legacy site's own white masthead. */
.site-header__logo {
    display: block;
    height: 30px;
}

/* The rotating client ad (ports legacy's header banner slot - the mobile
   header shows it between logo and menu too, tpl/m.header.php:4). Sits in
   the flexible middle of the header and scales down to whatever width the
   logo/nick/burger leave over - same squeeze legacy's own mobile header
   table applies. */
.site-header__ad {
    flex: 0 1 auto;
    min-width: 0;
    /* Phones: hidden here (the squeezed flex middle rendered banners
       unreadably small - user feedback); the .ad-strip below the header
       carries the banner instead. From 480px the masthead slot is wide
       enough to be legible. */
    display: none;
    align-items: center;
}

.ad-strip {
    display: flex;
    justify-content: center;
    padding: 0.3rem 1rem;
    background: var(--egun-surface);
    border-bottom: 1px solid var(--egun-border);
}

.ad-strip img {
    display: block;
    max-width: 100%;
    height: auto;
    max-height: 64px;
}

@media (min-width: 480px) {
    .site-header__ad {
        display: flex;
    }

    .ad-strip {
        display: none;
    }
}

.site-header__ad img {
    display: block;
    /* Matches the logo height - one masthead line, not floating images. */
    max-height: 30px;
    max-width: 100%;
    width: auto;
    height: auto;
}

.site-header__user {
    font-weight: 600;
    font-size: 0.9rem;
    color: var(--egun-blue);
    text-decoration: none;
    white-space: nowrap;
}

/* The desktop account-menu trigger (option A, 2026-08-08): hidden by
   default - the desktop layer switches it in for .site-header__user.
   Lives here only as a component default; all layout is desktop.css's. */
.site-header__account {
    display: none;
}

.site-header__toggle {
    background: none;
    border: none;
    color: var(--egun-blue);
    font-size: 1.4rem;
    line-height: 1;
    padding: 0.25rem 0.4rem;
    cursor: pointer;
}

/* Beats the global button:hover primary-fill (higher specificity when
   hovered) - the hamburger is an icon button, not a CTA. */
.site-header__toggle:hover {
    background: var(--egun-bg);
    color: var(--egun-blue);
}

/* Collapsed behind the toggle unconditionally (this app is mobile-first
   throughout, replacing m.egun.de - no separate wide-viewport layout to
   fall back to), not just under a breakpoint. Explicit [hidden]/:not()
   pairing rather than relying on `display:flex` alone to lose to the
   browser's UA [hidden]{display:none} rule - author CSS at equal
   specificity beats a UA rule regardless of source order, so a bare
   `.site-header__links { display:flex }` would otherwise defeat the
   `hidden` attribute entirely. */
.site-header__links {
    display: none;
}

.site-header__links:not([hidden]) {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: var(--egun-surface);
    border-bottom: 1px solid var(--egun-border);
    padding: 0.75rem 1rem 1rem;
    font-size: 0.95rem;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.12);
    max-height: calc(100vh - 100% - var(--tab-bar-h, 0rem));
    /* 100vh is the LARGEST mobile viewport (URL bar collapsed) - with
       the bar visible the sheet's tail (Abmelden) sat behind the
       browser chrome and the sheet never scrolled, while the page
       scrollbar uselessly moved the hidden content underneath (user
       report 2026-08-09). dvh tracks the viewport the user actually
       sees; browsers without it keep the vh line above. The bottom tab
       bar is opaque and fixed, so its height comes off too - the
       desktop layer zeroes the token, keeping its dropdown unclipped. */
    max-height: calc(100dvh - 100% - var(--tab-bar-h, 0rem));
    overflow-y: auto;
    /* a sheet at its scroll end must not hand the gesture to the page */
    overscroll-behavior: contain;
}

.site-header__links a {
    color: var(--egun-blue);
    text-decoration: none;
}

.site-header__nav-group {
    text-transform: uppercase;
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    color: var(--egun-text-muted);
    margin-top: 0.4rem;
    padding-bottom: 0.2rem;
    border-bottom: 1px solid var(--egun-border);
}

.site-header__nav-group:first-child {
    margin-top: 0;
}

.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
}

.site-main {
    max-width: 640px;
    margin: 0 auto;
    /* Top padding a step tighter than the sides: the masthead/ad strip
       above already provides separation (visible gap felt oversized on
       the home page - user feedback). */
    padding: 0.6rem 1rem 1rem;
}

/* --- Breadcrumb --- */

.breadcrumb {
    font-size: 0.85rem;
    color: var(--egun-text-muted);
    margin-bottom: 0.75rem;
}

/* --- Forms (search, login) --- */

.search-form,
form {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 1rem;
}

/* Fieldsets default to `min-width: min-content` in every browser, ignoring
   the flex/grid item shrinking rules that apply to everything else - a
   well-known CSS quirk that was overflowing the viewport on the Verkaufen
   page's Kategorie/Zweite Kategorie fieldsets specifically, since THEIR
   longest child (a <select> full of long category-path option labels) sets
   that min-content width.

   Beyond that fix, fieldsets are the section unit of every large data-entry
   form (sell, edit listing, registration, profile) - styled as cards
   matching .auction-pricing/.my-purchase-row, full-width within the parent
   form's flex flow, with their own internal flex flow so the label-above-
   field rules below apply per section. (.search-form__advanced fieldset
   keeps its own borderless compact override further down.) */
fieldset {
    min-width: 0;
    flex: 1 1 100%;
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.8rem 1rem 1rem;
    margin: 0;
}

legend {
    /* float != none opts the legend out of the browser's special
       on-the-border rendering (a long two-line legend gets the card
       border drawn THROUGH its second line - seen on registration's
       Sicherheitsfrage section). Inside our display:flex fieldsets the
       float itself is then ignored and the legend becomes an ordinary
       full-width flex item at the top of the card. */
    float: left;
    flex: 1 1 100%;
    font-weight: 700;
    padding: 0;
}

/* Field captions sit on their own line ABOVE their input (the previous
   pure flex-row flow let labels and inputs wrap side by side unpredictably
   - the main "fields hard to read" complaint). Checkbox/radio option
   labels are the exception: they stay inline-with-their-box and regular
   weight, so option lists don't read as section captions. */
fieldset > label {
    flex: 1 1 100%;
    font-weight: 600;
    margin-top: 0.4rem;
}

fieldset > label:has(input[type="checkbox"]),
fieldset > label:has(input[type="radio"]) {
    font-weight: 400;
    margin-top: 0;
}

fieldset > div {
    flex: 1 1 100%;
    /* Flex items default to min-width:auto (= min-content) - a child
       <select> with one long option (e.g. a security question) would
       otherwise blow this wrapper past the fieldset and force the whole
       page to scroll sideways. */
    min-width: 0;
}

/* Opt-in for a wrapper div INSIDE a fieldset whose children should follow
   the same label-above-field flow as the fieldset itself (e.g. the
   show/hide "Abwesenheitsnotiz" date fields on the preferences page). */
.fieldset-flow {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    min-width: 0; /* same min-content escape hatch as fieldset > div above */
}

.fieldset-flow > select {
    width: 100%; /* long <option> texts truncate inside instead of widening the row */
}

.fieldset-flow > label {
    flex: 1 1 100%;
    font-weight: 600;
    margin-top: 0.4rem;
}

.fieldset-flow > label:has(input[type="checkbox"]),
.fieldset-flow > label:has(input[type="radio"]) {
    font-weight: 400;
    margin-top: 0;
}

.fieldset-flow > input:not([type="checkbox"]):not([type="radio"]),
.fieldset-flow > select,
.fieldset-flow > textarea {
    flex: 1 1 100%;
}

/* Same label-above-field discipline for simple forms that have no
   fieldset sections of their own (wanted-ads, contact, violation report,
   recommendation ...) - opt-in via class, so intentionally-inline forms
   (login, the compact search bar) keep their row flow. */
.form-stack > label {
    flex: 1 1 100%;
    font-weight: 600;
    margin-top: 0.4rem;
}

.form-stack > label:has(input[type="checkbox"]),
.form-stack > label:has(input[type="radio"]) {
    font-weight: 400;
    margin-top: 0;
}

/* Each field takes its own full row too - otherwise the LAST input before
   the submit button shares a row with it (inputs are flex:1 1 auto
   globally), squeezing the field and gluing the button beside it (seen on
   login/forgot-password). Checkboxes/radios stay inline via their label. */
.form-stack > input:not([type="checkbox"]):not([type="radio"]),
.form-stack > select,
.form-stack > textarea,
.form-stack > details {
    flex: 1 1 100%;
}

/* <details> was the one child type without a full-row rule: COLLAPSED it
   is only as wide as its summary, and on any viewport wide enough the
   submit button climbed up beside "Ich habe keine Steuer-Identifikations-
   nummer" (user report 2026-08-08, /account/tax-details on desktop -
   expanding the fold "fixed" it because the inner fields force width). */

.form-stack > button[type="submit"] {
    margin-top: 0.6rem;
}

/* Shared captcha block (contact, violation report, recommendation) - the
   image and its "neues Bild" refresh link on one line, the code label/
   input following the same label-above-field flow as the rest of the
   form. */
.captcha {
    flex: 1 1 100%;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.captcha img {
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
}

.captcha label {
    flex: 1 1 100%;
    font-weight: 600;
    margin-top: 0.4rem;
}

.captcha input {
    flex: 1 1 100%;
}

.sell-image-thumbnails {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.5rem;
}

/* Drag-and-drop feedback on the Bilder fieldset (sell form): the gold
   dashed ring appears while a file drag hovers the section. The zone is
   the whole fieldset - no dedicated drop box, no extra strings; dropping
   feeds the same selection pipeline as the file picker. */
.sell-images-dropzone--over {
    outline: 2px dashed var(--egun-gold);
    outline-offset: 3px;
}

.sell-image-thumbnails__img {
    height: 100px;
    border-radius: var(--radius);
    object-fit: cover;
}

.sell-image-thumbnails__thumb {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    /* Room for badge + remove button side by side even under a very
       narrow (portrait) picture. */
    min-width: 6rem;
    align-items: center;
}

/* Badge left, remove right - IN FLOW above the picture, so neither ever
   covers the image or collides with the other on narrow uploads. */
.sell-image-thumbnails__bar {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.4rem;
    width: 100%;
}

.sell-image-thumbnails__remove {
    width: 1.5rem;
    height: 1.5rem;
    padding: 0;
    border-radius: 50%;
    background: var(--egun-red);
    color: #fff;
    font-size: 1rem;
    line-height: 1;
    border: none;
    flex: 0 0 auto;
}

/* Drag-to-sort on the picture itself (no handle icon, per user request).
   NO touch-action override here - a quick swipe over a picture must
   still scroll the page; the drag starts via long-press (see the sell
   form's startThumbDrag). The callout/user-select suppression stops
   iOS/Android from popping the image save-sheet during the long-press. */
.sell-image-thumbnails__img {
    cursor: grab;
    -webkit-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;
}

.sell-image-thumbnails__thumb--dragging {
    opacity: 0.6;
    outline: 2px solid var(--egun-gold);
    outline-offset: 2px;
    border-radius: var(--radius);
}

.sell-image-thumbnails__thumb--dragging .sell-image-thumbnails__img {
    cursor: grabbing;
}

.sell-image-sort-hint {
    flex: 1 1 100%;
    margin: 0.4rem 0 0;
    color: var(--egun-text-muted);
}

/* Drop-position preview: a gold edge on the side of the hovered
   thumbnail where the dragged one will land. */
.sell-image-thumbnails__thumb--drop-before {
    box-shadow: -4px 0 0 0 var(--egun-gold);
}

.sell-image-thumbnails__thumb--drop-after {
    box-shadow: 4px 0 0 0 var(--egun-gold);
}

.sell-image-thumbnails__main-badge {
    background: var(--egun-gold);
    color: var(--egun-text);
    font-size: 0.65rem;
    font-weight: 700;
    padding: 0.05rem 0.4rem;
    border-radius: 999px;
    white-space: nowrap;
}

/* Preview fallback when the browser can't decode the format (HEIC
   outside Safari): a named tile taking the picture's place. */
.sell-image-thumbnails__noview {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100px;
    height: 100px;
    padding: 0.3rem;
    border: 1px dashed var(--egun-border);
    border-radius: var(--radius);
    font-size: 0.65rem;
    color: var(--egun-text-muted);
    text-align: center;
    word-break: break-all;
    overflow: hidden;
    cursor: grab;
    -webkit-user-select: none;
    user-select: none;
}

/* Per-photo "Großes Bild" toggle - in flow BELOW the picture, same
   reasoning as the bar above it: never covers the image. */
.sell-image-thumbnails__large {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    font-size: 0.72rem;
    color: var(--egun-text-muted);
    white-space: nowrap;
    cursor: pointer;
}

.sell-image-thumbnails__large input {
    margin: 0;
    accent-color: var(--egun-gold);
}

.sell-preview__item {
    background: var(--egun-bg);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.8rem;
    margin-bottom: 1rem;
}

.sell-preview__item h1 {
    font-size: 1.3rem;
    margin: 0 0 0.4rem;
}

.sell-preview__category,
.sell-preview__images {
    color: var(--egun-text-muted);
    margin: 0 0 0.6rem;
}

.sell-preview {
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 1rem;
    margin-top: 1rem;
}

.sell-preview h2 {
    margin-top: 0;
}

.sell-preview__description {
    background: var(--egun-bg);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.6rem 0.8rem;
    margin: 0.8rem 0;
    overflow-x: auto;
}

/* --- Preisvorschlag (haggle) --- */

.auction-haggle {
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.9rem 1rem;
    margin-bottom: 1rem;
}

.auction-haggle h3 {
    margin: 0 0 0.6rem;
}

.auction-haggle__state {
    margin: 0 0 0.8rem;
}

.auction-haggle__form {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin: 0.6rem 0;
}

.auction-haggle__form label {
    flex: 1 1 100%;
    margin: 0;
    font-weight: 600;
}

.auction-haggle__form input[type="text"] {
    flex: 1 1 8rem;
    margin: 0;
}

.auction-haggle__form button {
    flex: 0 0 auto;
    margin: 0;
}

.auction-haggle__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0.6rem 0;
}

.auction-haggle__actions form {
    margin: 0;
}

.auction-haggle--waiting {
    color: var(--egun-text-muted);
    margin: 0;
}

.auction-haggle__history {
    margin-top: 0.8rem;
    font-size: 0.9rem;
}

.auction-haggle__history summary {
    cursor: pointer;
    color: var(--egun-text-muted);
}

.auction-haggle__history ul {
    margin: 0.4rem 0 0;
    padding-left: 1.2rem;
}

.auction-haggle-seller-hint {
    margin-bottom: 1rem;
}

.my-haggle-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.my-haggle-row {
    display: block;
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.8rem;
}

.my-haggle-row__title {
    font-weight: 600;
}

.my-haggle-row__meta {
    margin: 0.5rem 0 0.8rem;
    font-size: 0.9rem;
    line-height: 1.6;
}

.my-haggle-row__reject-form label {
    font-size: 0.85rem;
    font-weight: 400;
    color: var(--egun-text-muted);
    margin: 0;
}

.my-haggle-row__actions {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.my-haggle-row__actions form {
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.my-haggle-row__actions form label {
    margin: 0;
    font-weight: 400;
}

.my-haggle-row__actions input[type="text"] {
    flex: 1 1 8rem;
    margin: 0;
    max-width: 10rem;
}

.my-haggle-row__actions button {
    margin: 0;
}

.my-haggle-row__history {
    margin-top: 0.8rem;
    font-size: 0.9rem;
}

.my-haggle-row__history summary {
    cursor: pointer;
    color: var(--egun-text-muted);
}

.my-haggle-row__history ul {
    margin: 0.4rem 0 0;
    padding-left: 1.2rem;
}

.search-form--home {
    margin-top: 1rem;
}

input[type="text"],
input[type="password"],
input[type="number"],
input[type="date"],
input[type="email"],
input[type="search"],
textarea,
select {
    padding: 0.5rem 0.6rem;
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    font-size: 1rem;
    font-family: inherit;
    flex: 1 1 auto;
    min-width: 0;
    max-width: 100%;
    background: var(--egun-surface);
    color: var(--egun-text);
}

textarea {
    flex: 1 1 100%;
    resize: vertical;
}

input[type="file"] {
    flex: 1 1 100%;
    font-size: 0.95rem;
}

/* The native "Durchsuchen…"/"Choose Files" button was the one control on
   the sell form still wearing the browser's own chrome. Same tokens as
   .btn-quiet, so picking images looks like every other secondary action.
   ::file-selector-button is ignored by browsers that don't know it -
   they simply keep the native button, which is what happens today. */
input[type="file"]::file-selector-button {
    margin-right: 0.6rem;
    padding: 0.3rem 0.7rem;
    background: var(--egun-surface);
    color: var(--egun-text);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    font: inherit;
    font-size: 0.85rem;
    cursor: pointer;
}

input[type="file"]::file-selector-button:hover {
    background: var(--egun-bg);
}

label {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    font-size: 0.9rem;
}

/* Checkbox/radio option labels flow as normal text instead - as flex
   containers, a label with mixed content (text + a link, e.g. the AGB
   consent on registration) breaks into odd side-by-side columns, and
   multi-line option text can't wrap naturally around the box. */
label:has(input[type="checkbox"]),
label:has(input[type="radio"]) {
    display: block;
    line-height: 1.5;
}

button,
input[type="submit"],
.button-link {
    padding: 0.5rem 1.1rem;
    border: none;
    border-radius: var(--radius-control);
    background: var(--egun-blue);
    color: #fff;
    font-size: 1rem;
    font-weight: 600;
    cursor: pointer;
}

button:hover,
input[type="submit"]:hover,
.button-link:hover {
    background: var(--egun-blue-dark);
}

.button-link {
    display: inline-block;
    text-decoration: none;
}

/* Full-width variant, for link-buttons stacked with the item page's
   full-width action buttons (Bieten/Jetzt kaufen/Merkliste) - same box,
   same centering. */
.button-link--block {
    display: block;
    width: 100%;
    text-align: center;
    box-sizing: border-box;
}

/* Secondary look (surface + border, like .watchlist-toggle__button) for
   lower-priority actions such as "Verstoß melden" - button-shaped, but
   visually below the primary CTAs in the same stack. */
.button-link--secondary {
    background: var(--egun-surface);
    color: var(--egun-text);
    border: 1px solid var(--egun-border);
}

.button-link--secondary:hover {
    background: var(--egun-surface);
    border-color: var(--egun-blue);
}

/* Same visual treatment as a real <button>, for an <a> that navigates
   rather than submits a form (e.g. my-bid-row__rebid-button below) - kept
   generic/reusable rather than a one-off class, since this is the first
   link-styled-as-button case in the app. */
.button {
    display: inline-block;
    padding: 0.5rem 1.1rem;
    border-radius: var(--radius);
    background: var(--egun-blue);
    color: #fff;
    font-size: 1rem;
    font-weight: 600;
    text-decoration: none;
}

.button:hover {
    background: var(--egun-blue-dark);
    text-decoration: none;
}

/* --- Shared list-page primitives (Meine Verkäufe/Angebote/Käufe/...) --- */

/* Quiet secondary button for row-level side actions (Notiz, Bearbeiten,
   Als wiederverkauft markieren, ...) - the global <button> default is the
   full blue primary, which turned these pages into walls of equally loud
   buttons with no visual hierarchy. Works on <button> and <a> alike. */
.btn-quiet,
a.btn-quiet {
    display: inline-block;
    padding: 0.3rem 0.7rem;
    background: var(--egun-surface);
    color: var(--egun-text);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    font-size: 0.85rem;
    font-weight: 400;
    text-decoration: none;
    cursor: pointer;
}

.btn-quiet--pill,
a.btn-quiet--pill {
    border-radius: 999px;
}

.btn-quiet:hover,
a.btn-quiet:hover {
    background: var(--egun-surface);
    border-color: var(--egun-blue);
    color: var(--egun-blue);
}

/* Destructive flavor - same quiet weight, red accent on hover only. */
.btn-quiet--danger:hover {
    border-color: var(--feedback-negative);
    color: var(--feedback-negative);
}

/* Compact status pill for row states (Widerruf: eingereicht/akzeptiert/
   abgelehnt, Käufer erinnert, ...). Colors follow the feedback palette. */
.status-pill {
    display: inline-block;
    padding: 0.1rem 0.55rem;
    border-radius: 999px;
    font-size: 0.8rem;
    font-weight: 600;
    background: #eef0f3;
    color: var(--egun-text-muted);
    white-space: nowrap;
}

.status-pill--ok {
    background: #e6f4ea;
    color: #1a7a35;
}

.status-pill--bad {
    background: #fdecea;
    color: #b3261e;
}

.status-pill--pending {
    background: #fdf3dc;
    color: #8a6100;
}

/* Horizontal action cluster inside a row card - keeps mixed <a>/<form>/
   <button> children on one wrapping line with even gaps. */
.row-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    margin: 0.6rem 0 0;
}

.row-actions form {
    display: contents;
}

/* A .list-item rendered INSIDE an outer row card (Meine Angebote,
   Preisvorschläge) must not draw its own second card frame. */
.card-embed .list-item {
    background: transparent;
    border: none;
    border-radius: 0;
    padding: 0;
}

.error {
    background: #fdecea;
    color: #b3261e;
    border: 1px solid #f5c2c0;
    border-radius: var(--radius);
    padding: 0.6rem 0.8rem;
    width: 100%;
}

/* --- Flash messages (bid/buy-now feedback) --- */

.flash {
    padding: 0.6rem 0.8rem;
    border-radius: var(--radius);
    margin-bottom: 1rem;
}

.flash--success {
    background: #e6f4ea;
    color: #1a7a35;
    border: 1px solid #b7e1c1;
}

.flash--error {
    background: #fdecea;
    color: #b3261e;
    border: 1px solid #f5c2c0;
}

/* 'notice' = a persistent inline instruction the user must act on (e.g.
   confirm-your-email-change) - deliberately NOT a transient success toast. */
.flash--notice {
    background: #eef2fb;
    color: #23306b;
    border: 1px solid #c3cef0;
}

/* --- Category grid (home) --- */

.category-grid,
.subcategory-list,
.rubriken-grid {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    /* minmax(0, 1fr), NOT bare 1fr (= minmax(auto, 1fr)): a single long
       category name like "Selbstladebüchsen" would otherwise widen its
       column past half the viewport and push the whole grid sideways
       (user-reported on the home page). */
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.6rem;
}

.category-grid li a,
.subcategory-list li a,
.rubriken-grid li a {
    display: block;
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.9rem 0.75rem;
    color: var(--egun-text);
    font-weight: 600;
    text-decoration: none;
    text-align: center;
    /* Long German compound names wrap with hyphenation instead of
       overflowing the tile; `anywhere` is the last-resort fallback. */
    hyphens: auto;
    overflow-wrap: anywhere;
}

.category-grid li a:hover,
.subcategory-list li a:hover,
.rubriken-grid li a:hover {
    border-color: var(--egun-blue);
    color: var(--egun-blue);
}

/* Tablets and up (content column is 640px max): three shortcut tiles per
   row instead of two stretched ones. */
@media (min-width: 600px) {
    .category-grid,
    .subcategory-list,
    .rubriken-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

.subcategory-list {
    margin-bottom: 1rem;
}

/* --- Home page sections (Specials, Neue Top-Auktionen, Rubriken) --- */

.home-section {
    margin-bottom: 1.5rem;
}

.home-section h2 {
    font-size: 1.05rem;
    margin: 0 0 0.6rem;
}

.home-section__more {
    display: inline-block;
    margin-top: 0.5rem;
    font-weight: 600;
}

/* --- Auction list / list item --- */

.auction-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.list-item {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    width: 100%;
    min-width: 0;
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.6rem;
}

.list-item:hover {
    border-color: var(--egun-blue);
}

.list-item__link {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    flex: 1 1 auto;
    min-width: 0;
    color: var(--egun-text);
    text-decoration: none;
}

.list-item__link:hover {
    text-decoration: none;
}

/* Watch star at the card's TOP-RIGHT corner (user request 2026-07-17),
   out of the horizontal flow - which also hands its former column width
   to the body, exactly the space the one-line "12 Gebote ... 12 Tage,
   x Std, y Min" meta needed to stop wrapping on 2-digit values. */
.list-item__watch-form,
.list-item__watch--disabled {
    position: absolute;
    top: 0.3rem;
    right: 0.45rem;
    margin: 0;
}

.list-item__thumb {
    flex: 0 0 auto;
    width: 64px;
    height: 64px;
    border-radius: 6px;
    overflow: hidden;
    background: var(--egun-bg);
    display: flex;
    align-items: center;
    justify-content: center;
}

.list-item__thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    /* UX audit N2: a broken image renders its alt text (now the full
       auction title) - keep it unobtrusive inside the 64px box. */
    overflow: hidden;
    font-size: 0.55rem;
    line-height: 1.1;
    color: var(--egun-text-muted);
    word-break: break-word;
}

.list-item__body {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.list-item__title {
    /* FULL title, no clamp (user decision 2026-07-17, reversing the
       earlier 2-line ellipsis): at this reduced size a complete long
       title costs ~3 short lines and identifies the item beyond doubt -
       the earlier clamp hid the distinguishing details sellers put at
       the end (caliber, condition). */
    display: block;
    min-width: 0;
    /* keeps the first line clear of the corner watch star */
    padding-right: 1.6rem;
    font-size: 0.85rem;
    line-height: 1.3;
    /* half a step under bold: the PRICE is the card's loud line, the
       title the quiet descriptive one (print-catalog hierarchy). */
    font-weight: 500;
    /* A single unbroken "word" (no spaces - a real title seen in
       production) must not blow the row wider than the viewport, but the
       earlier fix (word-break:break-all) broke EVERY word at the line
       edge ("k"/"ein" for "kein" - user-reported). overflow-wrap:anywhere
       is the correct tool: normal words wrap at spaces as usual, and a
       break inside a word is taken ONLY when that word can't fit on a
       line by itself. Unlike break-word it also counts these break
       opportunities into min-content sizing, so the nested-flex chain
       here can't be blown out by a long token either (the reason
       break-all was originally reached for). break-word stays as the
       fallback for engines without `anywhere` support. Deliberately NOT
       single-line nowrap+ellipsis (the pre-break-all approach) - that
       depends on the whole flex min-width chain resolving to a definite
       width before shrinking kicks in, which doesn't reliably happen in
       nested flex containers whose own width resolves from content. */
    overflow-wrap: break-word;
    overflow-wrap: anywhere;
}

.list-item__meta {
    display: flex;
    align-items: center;
    gap: 0.1rem 0.5rem;
    min-width: 0;
    font-size: 0.8rem;
    color: var(--egun-text-muted);
    /* One line in the common case; when a long price + bid count + end
       time genuinely don't fit, the end time wraps to a second line
       instead of truncating information (ellipsizing "(10 Gebote)" to
       "(10 G…" helped nobody - user feedback). Each part is atomic
       (nowrap on the children), breaks only happen BETWEEN parts. */
    flex-wrap: wrap;
}

/* Auktionspuls hairline along the card's bottom edge (see
   _list_item.html.twig) - width = elapsed share of the auction's
   timespan, red in the final hour. */
.list-item {
    position: relative;
}

.list-item__pulse {
    position: absolute;
    left: 0;
    bottom: 0;
    height: 2px;
    max-width: 100%;
    background: var(--egun-gold);
    /* both bottom corners: a 100% bar must follow the card's rounding */
    border-bottom-left-radius: var(--radius);
    border-bottom-right-radius: var(--radius);
    pointer-events: none;
}

.list-item__pulse--critical {
    background: var(--egun-red);
}

/* List cards: the price gets its own line in the display face -
   scannable like a printed price column. */
.list-item__price-line {
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
    min-width: 0;
}

.list-item__price {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 1.2rem;
    color: var(--egun-text);
    font-variant-numeric: tabular-nums;
    flex: 0 0 auto;
}

/* What the number IS (Sofortkauf / Aktuelles Gebot / Startpreis) - hidden
   on the phone's compact rows, revealed by the desktop layer. */
.list-item__price-label {
    display: none;
    font-size: 0.72rem;
    color: var(--egun-text-muted);
    white-space: nowrap;
}

/* Desktop-ledger copy of the bid/stock count under the price - hidden
   here, the desktop layer's ledger rules reveal it and hide the meta
   copy (user request 2026-08-09). */
.list-item__price-sub {
    display: none;
    font-size: 0.8rem;
    color: var(--egun-text-muted);
    white-space: nowrap;
}

/* The condition/Händler pill line under the title (one home for the
   pills in EVERY layout - phone row, home rail, desktop ledger). Block
   inside the inline-flow title span, so it always starts on its own
   line regardless of how the surrounding cell flexes. */
.list-item__tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
    margin-top: 0.3rem;
    font-size: 0.72rem;
}

.list-item__haggle {
    font-size: 0.75rem;
    color: var(--egun-text-muted);
    white-space: nowrap;
}

.list-item__bids,
.list-item__qty,
.list-item__ends {
    flex: 0 0 auto;
    white-space: nowrap;
}

.list-item__ends {
    margin-left: auto;
}

/* Under one hour the remaining time itself turns urgent - same threshold
   as the Auktionspuls' critical state and the "endet bald" badge. */
.list-item__ends--critical {
    color: var(--egun-red);
    font-weight: 600;
}

.list-item__watch {
    flex: 0 0 auto;
    font-size: 1.3rem;
    line-height: 1;
    color: var(--egun-border);
    background: none;
    border: none;
    /* >=44x44 touch target (UX audit H5): pad the hit area, pull the
       padding back out with negative margin so the layout stays put. */
    padding: 0.7rem;
    margin: -0.7rem;
    cursor: pointer;
}

.list-item__watch--active {
    color: var(--egun-gold);
}

/* Anonymous star: muted look, but it IS a link (to the login page) -
   so it must FEEL like one: pointer cursor, never the link underline
   (an underscored ☆ read as a rendering glitch, user-reported). */
.list-item__watch--disabled,
a.list-item__watch--disabled {
    color: var(--egun-border);
    cursor: pointer;
    text-decoration: none;
}

a.list-item__watch--disabled:hover {
    color: var(--egun-text-muted);
    text-decoration: none;
}

.empty-state {
    list-style: none;
    text-align: center;
    color: var(--egun-text-muted);
    padding: 2rem 1rem;
}

/* --- Badges --- */

/* --- Watchlist --- */

/* Full-width card with an X button floating on its upper-right corner
   (replaced the old checkbox-per-row + "Ausgewählte entfernen" batch
   form, which squeezed every card). */
.watchlist-list__row {
    position: relative;
    min-width: 0;
}

.watchlist-list__row .list-item {
    min-width: 0;
    /* keep the title clear of the remove button */
    padding-right: 2.6rem;
}

/* The per-card remove form must not add the global form margin-bottom -
   card spacing comes from the list's own gap, same as on the home page. */
.watchlist-list__remove-form {
    margin: 0;
}

.watchlist-list__remove {
    position: absolute;
    top: 0.4rem;
    right: 0.4rem;
    display: grid;
    place-items: center;
    width: 2rem;
    height: 2rem;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--egun-text-muted);
    cursor: pointer;
}

.watchlist-list__remove:hover,
.watchlist-list__remove:focus-visible {
    background: rgba(0, 0, 0, 0.06);
    color: var(--egun-red);
}

.watchlist-list__remove svg {
    width: 1.05rem;
    height: 1.05rem;
}

.watchlist-toggle {
    margin-bottom: 1rem;
}

.watchlist-toggle__button {
    width: 100%;
    background: var(--egun-surface);
    color: var(--egun-text);
    border: 1px solid var(--egun-border);
}

.watchlist-toggle__button:hover {
    background: var(--egun-surface);
    border-color: var(--egun-blue);
}

.watchlist-toggle__button--active {
    border-color: var(--egun-gold);
    color: #4a3600;
    background: #fff8e1;
}

.watchlist-toggle--disabled {
    color: var(--egun-text-muted);
    font-size: 0.9rem;
}

/* --- Buy-now / bid forms --- */

.buy-now-form,
.bid-form {
    margin-bottom: 1rem;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
}

.buy-now-form__button,
.bid-form__button {
    width: 100%;
    background: var(--egun-gold);
    color: #4a3600;
    font-weight: 700;
}

.buy-now-form__button:hover,
.bid-form__button:hover {
    background: #e6b800;
}

.buy-now-form--disabled,
.bid-form--disabled {
    color: var(--egun-text-muted);
    font-size: 0.9rem;
}

.badge {
    display: inline-block;
    font-size: 0.7rem;
    font-weight: 700;
    padding: 0.1rem 0.4rem;
    border-radius: 4px;
    background: var(--egun-border);
    color: var(--egun-text);
    vertical-align: middle;
}

.badge--new {
    background: var(--egun-gold);
    color: #4a3600;
}

/* "Neu dabei" member chip (2026-07-21): the modern successor of legacy's
   cool.gif sunglasses smilie for accounts younger than one month. Soft
   blue = information, not celebration - it's a trust fact. */
.badge--member-new {
    background: #eaf1fb;
    color: #23508c;
    font-weight: 600;
}

/* Score link (tier pills removed 2026-07-21 by user decision). */
.score-chip {
    text-decoration: none;
    font-weight: 600;
}

.badge--legal {
    background: var(--egun-red);
    color: #fff;
}

/* "endet bald" (social proof, 2026-07-21): red urgency, same threshold as
   the red Auktionspuls (< 1h). */
.badge--ending {
    background: var(--egun-red);
    color: #fff;
}

.badge--certified {
    background: #1a8a3d;
    color: #fff;
}

/* The "ID" identity-verification chip (replaces the bare green hook on
   the item page): display face on the trust green, with an inset
   keyline that gives it the feel of a small ID card. It's a BUTTON -
   tapping opens the certification explainer popover. */
.badge--id {
    display: inline-flex;
    align-items: center;
    padding: 0.1rem 0.4rem;
    border: none;
    border-radius: 3px;
    background: #1a8a3d;
    color: #fff;
    font-family: var(--font-display);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    line-height: 1.3;
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.35);
    cursor: pointer;
    vertical-align: middle;
}

.badge--id:hover {
    background: #1a8a3d;
}

/* "gewerblich": a quiet outlined pill instead of the gray fill - a
   professional label, not a tag. */
.badge--business {
    background: transparent;
    border: 1px solid var(--egun-border);
    color: var(--egun-text-muted);
    font-family: var(--font-display);
    font-weight: 600;
    letter-spacing: 0.04em;
    border-radius: 999px;
    padding: 0.1rem 0.5rem;
}

/* Artikelzustand on cards: the same quiet outlined pill as "gewerblich"
   (user feedback 2026-08-08) - carries its "Zustand:" prefix in the
   markup so a "Neu" value can't be mistaken for the red new-listing
   badge. */
.badge--condition {
    background: transparent;
    border: 1px solid var(--egun-border);
    color: var(--egun-text-muted);
    font-family: var(--font-display);
    font-weight: 600;
    letter-spacing: 0.04em;
    border-radius: 999px;
    padding: 0.1rem 0.5rem;
}

/* Certification explainer (native popover, centered by the UA). */
.cert-popover {
    max-width: 320px;
    padding: 1rem 1.1rem;
    border: 1px solid var(--egun-border);
    border-left: 3px solid #1a8a3d;
    border-radius: var(--radius);
    background: var(--egun-surface);
    color: var(--egun-text);
    box-shadow: 0 8px 30px rgba(0, 0, 0, 0.25);
}

.cert-popover p {
    margin: 0.5rem 0 0;
    padding-right: 1.2rem;
    font-size: 0.9rem;
    line-height: 1.45;
}

.cert-popover strong {
    display: block;
    padding-right: 1.6rem;
}

.cert-popover__close {
    position: absolute;
    top: 0.4rem;
    right: 0.4rem;
    width: 1.7rem;
    height: 1.7rem;
    padding: 0;
    border: none;
    border-radius: 50%;
    background: transparent;
    color: var(--egun-text-muted);
    font-size: 1.2rem;
    line-height: 1;
    cursor: pointer;
}

.cert-popover__close:hover {
    background: rgba(0, 0, 0, 0.06);
    color: var(--egun-text);
}

/* The desktop myGun mark (images/mygun.gif) as crisp text: "my" in red
   italic, G/u/n in the wordmark colors - an outlined pill like the
   gewerblich badge (brand vars adapt to dark mode automatically). */
.mygun-mark {
    display: inline-flex;
    align-items: baseline;
    padding: 0.1rem 0.55rem;
    border: 1px solid var(--egun-border);
    border-radius: 999px;
    background: var(--egun-surface);
    font-family: var(--font-display);
    font-size: 0.85rem;
    font-weight: 600;
    line-height: 1.2;
    text-decoration: none;
}

.mygun-mark:hover {
    text-decoration: none;
}

.mygun-mark em {
    color: var(--egun-red);
    font-style: italic;
    margin-right: 0.06em;
}

/* Darker gold than the brand token: #ffcc33 disappears on the white
   pill (the dark-mode block restores the bright brand gold). */
.mygun-mark__g { color: #cf9d00; }
.mygun-mark__u { color: var(--egun-blue); }
.mygun-mark__n { color: var(--egun-green); }

.auction-seller__address {
    margin: 0.35rem 0 0.5rem;
    color: var(--egun-text-muted);
    font-style: normal; /* <address> defaults to italic in some UAs */
    line-height: 1.35;
}

.cert-popover::backdrop {
    background: rgba(0, 0, 0, 0.25);
}

.badge--mygun {
    background: var(--egun-blue);
    color: #fff;
    text-decoration: none;
}

.cafe-post__rating {
    font-size: 0.85rem;
    color: var(--egun-text-muted);
}

/* --- Pagination --- */

.pagination {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    margin-top: 1rem;
    padding-top: 1rem;
    border-top: 1px solid var(--egun-border);
    font-size: 0.85rem;
    color: var(--egun-text-muted);
}

/* The pills are atomic controls - they must never break internally («
   ending up above "Zurück", user report 2026-07-21). The middle status
   text is the flexible element instead: it takes the remaining space,
   centers, and wraps ITS words when the row gets tight. */
.pagination a {
    white-space: nowrap;
    flex-shrink: 0;
}

/* Numbered page links: rendered by _pagination.html.twig for every
   viewport but shown only by the desktop layer (desktop.css) - on a
   phone Zurück/Weiter plus "Seite X von Y" is the right amount of
   control, and with the desktop layer off this cluster never appears. */
.pagination__pages {
    display: none;
}

.pagination span {
    flex: 1;
    min-width: 0;
    text-align: center;
}

/* --- Item detail --- */

.auction-gallery-wrap {
    position: relative;
    margin-bottom: 0.5rem;
}

.auction-gallery {
    display: flex;
    gap: 0.5rem;
    overflow-x: auto;
    scroll-snap-type: x proximity;
}

.auction-gallery img {
    height: 220px;
    /* A panoramic image at 220px height can come out wider than the
       viewport, forcing the user to scroll sideways just to see ONE
       image (user-reported). Cap it at the gallery width; object-fit
       keeps the full image visible at its own aspect ratio inside the
       capped box instead of squashing it. */
    max-width: 100%;
    object-fit: contain;
    border-radius: var(--radius);
    flex: 0 0 auto;
    scroll-snap-align: start;
}

.auction-gallery img {
    cursor: zoom-in;
}

/* Gallery overlay controls (redesign 2026-07-21, replacing the hint text,
   the right-edge fade AND the auto-advance): one device family - dark
   glass chips floating on the photo. Scrim + white glyphs stay readable
   on any picture, light or dark. */
.gallery-chips {
    position: absolute;
    top: 0.5rem;
    right: 0.5rem;
    display: flex;
    align-items: center;
    gap: 0.4rem;
    z-index: 2;
}

.gallery-chips form {
    margin: 0;
    display: contents;
}

.gallery-chip,
a.gallery-chip {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.3rem;
    min-width: 2.2rem;
    height: 2.2rem;
    padding: 0 0.6rem;
    border: 0;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.5);
    color: #fff;
    font-size: 1.05rem;
    font-weight: 400;
    line-height: 1;
    cursor: pointer;
    text-decoration: none;
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
}

.gallery-chip:hover,
a.gallery-chip:hover {
    background: rgba(0, 0, 0, 0.68);
    color: #fff;
}

.gallery-chip__count {
    font-size: 0.8rem;
    font-weight: 600;
}

.gallery-chip--watched .gallery-chip__star {
    color: var(--egun-gold);
}

/* Side markers: the "more pictures" affordance, same glass finish,
   vertically centered on the strip. Hidden at the respective end via
   the [hidden] attribute (managed by the gallery script). */
.gallery-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 2;
    width: 2.2rem;
    height: 2.2rem;
    padding: 0 0 0.2rem;
    border: 0;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.5);
    color: #fff;
    font-size: 1.5rem;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}

.gallery-nav:hover {
    background: rgba(0, 0, 0, 0.68);
    color: #fff;
}

.gallery-nav[hidden] {
    display: none;
}

.gallery-nav--prev {
    left: 0.5rem;
}

/* View-counter chip: same glass finish, lower left, NOT interactive -
   no hover state, default cursor. */
.gallery-chip--views {
    position: absolute;
    bottom: 0.5rem;
    left: 0.5rem;
    z-index: 2;
    cursor: default;
}

.gallery-chip--views:hover {
    background: rgba(0, 0, 0, 0.5);
}

.gallery-nav--next {
    right: 0.5rem;
}

/* More vertical room for auction pictures on tablets - the 220px strip
   is a phone-screen compromise. */
@media (min-width: 600px) {
    .auction-gallery img {
        height: 320px;
    }
}

/* --- PWA install banner --- */

.pwa-install-banner {
    position: fixed;
    left: 0.6rem;
    right: 0.6rem;
    bottom: 0.6rem;
    z-index: 900;
    display: flex;
    align-items: center;
    gap: 0.7rem;
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.18);
    padding: 0.7rem 0.8rem;
}

.pwa-install-banner__icon {
    border-radius: 8px;
    flex: 0 0 auto;
}

.pwa-install-banner__text {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    font-size: 0.85rem;
    min-width: 0;
}

.pwa-install-banner__actions {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    flex: 0 0 auto;
}

.pwa-install-banner__actions button {
    font-size: 0.85rem;
    padding: 0.35rem 0.8rem;
    white-space: nowrap;
}

/* --- Gallery lightbox (tap an auction picture for full size) --- */

.gallery-lightbox {
    position: fixed;
    inset: 0;
    z-index: 1000;
    background: rgba(0, 0, 0, 0.88);
    display: flex;
    align-items: center;
    justify-content: center;
}

.gallery-lightbox[hidden] {
    display: none;
}

.gallery-lightbox__img {
    max-width: 96vw;
    max-height: 92vh;
    object-fit: contain;
    cursor: zoom-in;
    /* pointer-events pinch/pan needs the browser gestures off */
    touch-action: none;
    will-change: transform;
    transform-origin: center center;
}

.gallery-lightbox--zoomed .gallery-lightbox__img {
    cursor: grab;
}

.gallery-lightbox__close,
.gallery-lightbox__nav {
    position: absolute;
    background: rgba(0, 0, 0, 0.5);
    color: #fff;
    border: none;
    border-radius: 50%;
    width: 2.6rem;
    height: 2.6rem;
    padding: 0;
    font-size: 1.6rem;
    line-height: 1;
    cursor: pointer;
}

.gallery-lightbox__close:hover,
.gallery-lightbox__nav:hover {
    background: rgba(0, 0, 0, 0.75);
}

.gallery-lightbox__close {
    top: 0.8rem;
    right: 0.8rem;
}

.gallery-lightbox__nav--prev { left: 0.5rem; top: 50%; transform: translateY(-50%); }
.gallery-lightbox__nav--next { right: 0.5rem; top: 50%; transform: translateY(-50%); }

.gallery-lightbox__counter {
    position: absolute;
    bottom: 0.9rem;
    left: 50%;
    transform: translateX(-50%);
    color: #fff;
    font-size: 0.85rem;
    background: rgba(0, 0, 0, 0.5);
    padding: 0.15rem 0.7rem;
    border-radius: 999px;
}

/* No page scroll behind the open lightbox. */
body.gallery-lightbox-open {
    overflow: hidden;
}

.auction-legal-disclosures {
    background: #fff8e1;
    border: 1px solid var(--egun-gold);
    border-radius: var(--radius);
    padding: 0.75rem 1rem;
    margin-bottom: 1rem;
}

.disclosure {
    margin: 0.5rem 0;
}

.auction-pricing {
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.9rem 1rem;
    margin-bottom: 1rem;
}

/* Lot header: breadcrumb + title in one card, matching the page's
   card-based surface language. */
.item-head {
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.75rem 1rem 0.85rem;
    margin-bottom: 1rem;
}

.item-head__breadcrumb {
    margin: 0 0 0.3rem;
    font-size: 0.78rem;
    color: var(--egun-text-muted);
}

/* The paid second category as its own line under the primary
   breadcrumb (2026-08-10 - legacy always showed it). */
.item-head__breadcrumb--second {
    margin-top: -0.15rem;
}

.item-head__title {
    margin: 0;
    font-size: 1.3rem;
    line-height: 1.3;
    overflow-wrap: anywhere;
}

/* --- Trade card ------------------------------------------------------
   On the item page, pricing + countdown + all actions (bid, buy now,
   haggle, watchlist) compose into ONE card instead of loose sibling
   boxes - the child partials keep their own standalone styling
   elsewhere (sell-form preview), so all flattening is scoped here. */
.trade-card {
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    overflow: hidden;
    margin-bottom: 1rem;
}

/* The Auktionspuls: the card's top edge fills with the auction's real
   elapsed time - gold while running, red inside the final hour. Driven
   by the detail-page tick loop; stays hidden without JS or when the
   auction is closed / not yet started. */
.trade-card__pulse {
    height: 4px;
    background: var(--egun-bg);
}

.trade-card__pulse span {
    display: block;
    height: 100%;
    width: 0;
    background: var(--egun-gold);
    transition: width 1s linear;
}

.trade-card__pulse--critical span {
    background: var(--egun-red);
}

@media (prefers-reduced-motion: reduce) {
    .trade-card__pulse span {
        transition: none;
    }
}

.trade-card .auction-pricing {
    background: none;
    border: 0;
    border-radius: 0;
    margin-bottom: 0;
}

.trade-card .bid-form,
.trade-card .buy-now-form,
.trade-card .watchlist-toggle {
    margin: 0;
    padding: 0 1rem 0.8rem;
}

/* (The watch row used to close the card with 1rem; since the share/
   recommend rows moved in below it, the last link-row does that.) */

.trade-card .auction-haggle {
    background: none;
    border: 0;
    border-radius: 0;
    margin: 0;
    padding: 0 1rem 0.8rem;
}

/* Extended shipping-cost EDITOR (sell/edit forms): the Versandarten are
   defined once as a list, then every Zielland is its own stacked "tariff
   card" with one price field per Versandart - purely vertical, so it can
   never overflow a phone viewport sideways (the old Versandart x Zielland
   matrix <table> forced far-right scrolling - user-reported). */
.ext-shipping__hint {
    font-size: 0.85rem;
    color: var(--egun-text-muted);
    margin: 0.2rem 0 0.6rem;
}

/* Matrix editor (2026-08-09, replacing the three abstract name-lists +
   separate price cards): the grid IS the buyer-facing table - bordered
   like the item page's shipping table, prices typed straight into the
   cells. Labels live in the FIRST carrier block only (the blob shares
   types/destinations across carriers); later blocks mirror them. On
   narrow screens the grid scrolls horizontally in its own wrapper with
   the row-label column pinned. */
#ext-matrix {
    display: grid;
    gap: 1.1rem;
}

.ext-matrix__carrier {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.6rem;
    margin-bottom: 0.45rem;
}

.ext-matrix__carrier-label {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.85rem;
    color: var(--egun-text-muted);
}

.ext-matrix__carrier-label input {
    width: 14em;
}

.ext-matrix__scroll {
    overflow-x: auto;
}

.ext-matrix__table {
    border-collapse: collapse;
}

.ext-matrix__table th,
.ext-matrix__table td {
    border: 1px solid var(--egun-border);
    padding: 0.35rem 0.45rem;
    text-align: left;
    vertical-align: middle;
    background: var(--egun-surface);
}

.ext-matrix__corner,
.ext-matrix__type {
    /* pinned while the price columns scroll on narrow screens */
    position: sticky;
    left: 0;
    z-index: 1;
}

.ext-matrix__corner {
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--egun-text-muted);
}

.ext-matrix__dest {
    font-weight: 600;
}

.ext-matrix__type {
    font-weight: 500;
}

.ext-matrix__labelwrap {
    display: inline-flex;
    align-items: center;
    gap: 0.2rem;
}

.ext-matrix__labelwrap input {
    width: 9.5em;
}

.ext-matrix__price {
    display: inline-flex;
    align-items: baseline;
    gap: 0.25rem;
    white-space: nowrap;
}

.ext-matrix__price input {
    width: 5em;
    text-align: right;
}

/* The growth affordances render as dashed "ghost" cells - visibly not
   part of the buyer-facing table. */
.ext-matrix__add-cell,
.ext-matrix__add-row th,
.ext-matrix__add-row td {
    border-style: dashed;
    background: transparent;
    white-space: nowrap;
}

.ext-matrix__add-row th {
    position: sticky;
    left: 0;
}

.ext-matrix__rm {
    background: none;
    border: none;
    color: var(--egun-text-muted);
    font-size: 1.05rem;
    line-height: 1;
    padding: 0.05rem 0.25rem;
    cursor: pointer;
}

.ext-matrix__rm:hover {
    background: none;
    color: var(--egun-red);
}

.ext-matrix__add-carrier-row {
    margin: 0;
}

/* --- Sell/edit form overhaul --- */

/* Section legends as eyebrow labels, each carrying the Verkaufen world
   dot (the dashboard's wordmark color coding: Verkaufen = the e's red) -
   a long legal-heavy form scans by section this way. */
.sell-form legend {
    display: flex;
    align-items: center;
    gap: 0.45em;
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.09em;
    color: var(--egun-text-muted);
}

.sell-form legend::before {
    content: '';
    flex: none;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--egun-red);
}

/* Radio/checkbox groups as tappable pills - the same visual vocabulary
   as the search page's sort chips, selected = blue fill. The native
   input stays visible inside the pill (a11y, and state survives even
   without :has support). */
.choice-pills {
    flex: 1 1 100%;
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

fieldset > .choice-pills label,
.choice-pills label {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    flex: none;
    max-width: 100%;
    margin: 0;
    padding: 0.3rem 0.75rem;
    border: 1px solid var(--egun-border);
    border-radius: 999px;
    background: var(--egun-surface);
    font-size: 0.9rem;
    font-weight: 400;
    cursor: pointer;
}

.choice-pills label:hover {
    border-color: var(--egun-blue);
}

.choice-pills label:has(input:checked) {
    border-color: var(--egun-blue);
    background: var(--egun-blue);
    color: #fff;
}

.choice-pills label:has(input:focus-visible) {
    outline: 2px solid var(--egun-blue);
    outline-offset: 2px;
}

.choice-pills__price {
    font-size: 0.8rem;
    font-weight: 600;
    padding: 0.05em 0.5em;
    border-radius: 999px;
    background: var(--egun-gold);
    color: #1a1a1a;
    white-space: nowrap;
}

/* "Nur erlaubnisfreie Artikel" - the always-visible permit filter on
   search (a checkbox label) and category pages (a toggle chip link). */
.permit-free-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    font-size: 0.9rem;
}

.permit-free-toggle--chip {
    margin: 0 0 0.8rem;
    padding: 0.35rem 0.7rem;
    border: 1px solid var(--egun-border);
    border-radius: 999px;
    background: var(--egun-surface);
    color: var(--egun-text);
    text-decoration: none;
}

.permit-free-toggle--active {
    border-color: var(--egun-green, #2e7d32);
    font-weight: 600;
}

.permit-free-toggle__box {
    display: inline-grid;
    place-items: center;
    width: 1.05rem;
    height: 1.05rem;
    border: 1px solid var(--egun-border);
    border-radius: 4px;
    font-size: 0.8rem;
    line-height: 1;
}

.permit-free-toggle--active .permit-free-toggle__box {
    background: var(--egun-green, #2e7d32);
    border-color: var(--egun-green, #2e7d32);
    color: #fff;
}

/* Live fee total under the sell form. */
.sell-fee-line {
    flex: 1 1 100%;
    margin: 0.3rem 0 0;
    font-size: 0.9rem;
    color: var(--egun-text-muted);
}

/* Draft-restored notice above the sell form. */
.sell-draft-notice {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    margin: 0 0 1rem;
    padding: 0.55rem 0.75rem;
    border: 1px solid var(--egun-border);
    border-left: 3px solid var(--egun-gold);
    border-radius: var(--radius);
    background: var(--egun-surface);
    font-size: 0.9rem;
}

/* Vorschau + Artikel einstellen at the end of the form (not sticky:
   the form must be filled out completely before either is useful). */
.sell-actions {
    flex: 1 1 100%;
    display: flex;
    gap: 0.5rem;
    margin-top: 0.5rem;
    padding: 0.6rem 0;
    border-top: 1px solid var(--egun-border);
}

.sell-actions button {
    flex: 1 1 50%;
}

.sell-actions .sell-actions__secondary {
    background: var(--egun-surface);
    color: var(--egun-text);
    border: 1px solid var(--egun-border);
}

.sell-actions .sell-actions__secondary:hover {
    background: var(--egun-surface);
    border-color: var(--egun-blue);
}

/* Extended shipping costs (per-destination seller tables): a real small
   table - unlike seller description tables these are genuinely tabular
   and stay narrow; anything wider scrolls inside its own box. */
.shipping-ext {
    overflow-x: auto;
    margin: 0.6rem 0 0;
}

.shipping-ext__table {
    border-collapse: collapse;
    /* As compact as still readable: a label column plus 2 price columns
       must fit a narrow phone WITHOUT the inner horizontal scroll
       (user-reported via a DHL table 11px too wide). The wrapper's
       overflow-x stays as the fallback for genuinely wide 4+-column
       international tables. */
    font-size: 0.8rem;
    min-width: 100%;
}

.shipping-ext__table th,
.shipping-ext__table td {
    border: 1px solid var(--egun-border);
    padding: 0.3rem 0.35rem;
    text-align: left;
    vertical-align: top;
    /* Long carrier terms ("Sendungsnummer") set the label column's
       min-content width - let them hyphenate instead. */
    hyphens: auto;
}

.shipping-ext__table thead th {
    background: var(--egun-bg);
}

.shipping-ext__table td {
    white-space: nowrap;
    text-align: right;
}

/* Section eyebrows: the quiet uppercase labels of the dashboard, forms
   and help page. The item page's card headings deliberately do NOT use
   this device anymore - they are the page's content architecture, not
   form labels, and vanished at eyebrow volume (user report 2026-07-18);
   they get the catalog-heading treatment below instead. */
.section-eyebrow {
    margin: 0 0 0.5rem;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--egun-text-muted);
}

.section-eyebrow {
    margin: 1.1rem 0 0.45rem;
}

.auction-status--closed {
    color: var(--egun-red);
    font-weight: 700;
}

.auction-restzeit {
    font-size: 1.1rem;
    /* tight to the Ende line directly beneath */
    margin: 0.5rem 0 0.1rem;
}

/* The ticking digits get the display face and tabular figures so the
   countdown doesn't jitter, and a touch more size - the deadline IS the
   auction. */
.auction-restzeit strong {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 1.3em;
    font-variant-numeric: tabular-nums;
}

.auction-restzeit--ended,
.auction-restzeit--future {
    color: var(--egun-red);
}

.auction-timespan {
    display: flex;
    flex-wrap: wrap;
    gap: 0 1.5rem;
    font-size: 0.9rem;
    color: var(--egun-text-muted);
    margin: 0;
}

/* Label and amount are deliberately near-equal (user request 2026-07-15):
   the label ("Sofortkauf:" / "Aktuelles Gebot:" and their translations)
   at the amount's original 1.4rem, the amount itself 2px smaller. The
   explicit __label/__amount classes also fix the old `.price span` rule
   accidentally shrinking the auction amount, whose live-updating value
   is a <span data-live="price"> rather than a bare text node. */
.price {
    margin: 0 0 0.4rem;
}

.price__label {
    font-size: 1.4rem;
    font-weight: 400;
    color: var(--egun-text-muted);
}

/* The amount is the protagonist: display face, tabular figures, a step
   above its label - an auction page should be readable from arm's
   length by its numbers alone. */
.price__amount {
    font-family: var(--font-display);
    font-size: 1.65rem;
    font-weight: 600;
    letter-spacing: 0.01em;
    font-variant-numeric: tabular-nums;
}

/* The MwSt note gets its own quiet line - inline it wrapped mid-
   parenthesis next to the enlarged amount. */
.price small {
    display: block;
    color: var(--egun-text-muted);
}

.auction-seller,
.auction-shipping {
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.9rem 1rem;
    margin-bottom: 1rem;
}

/* Item-page card headings (Verkäufer, Versand & Zahlung, Beschreibung,
   AGB card): real headings in the catalog voice - the display face and
   full text color set them apart from the body, size stays a step below
   the article h1. :first-child on the description variant because the
   body is raw seller HTML that may carry its own h2s. */
.auction-seller h2,
.auction-shipping h2,
.auction-description > h2:first-child {
    margin: 0 0 0.5rem;
    font-size: 1.15rem;
    line-height: 1.2;
}

.auction-description {
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.9rem 1rem;
    /* Same vertical rhythm as the other item-page cards (.auction-seller,
       .auction-shipping) - also spaces the AGB card, which reuses this
       class, away from the description above it. */
    margin: 0 0 1rem;
    position: relative;
    overflow-wrap: break-word;
}

/* Sellers' descriptions can carry raw HTML from legacy's WYSIWYG editor
   (fixed-width images, wide tables, unbroken long strings) - shrink what
   CSS can (the img/table rules below), and let anything that still
   doesn't fit scroll inside its OWN inner box instead of blowing out the
   whole page's width (legacy's mobile view avoids this by rendering the
   description in its own iframe; this achieves the same visual result
   without one). A separate inner element (not overflow-x on the card
   itself) so the edge-fade hint below can be a non-scrolling sibling,
   pinned to the card's own edge instead of scrolling away with the
   content it's hinting about. */
.auction-description__scroll {
    overflow-x: auto;
    overflow-wrap: break-word;
}

/* Scroll affordance for the rare box that's actually wider than the
   screen (JS-gated in app.js - only overflowing boxes get the class):
   a right-edge shadow hints "more content this way" instead of the raw
   content just looking clipped mid-image, and fades itself out once
   scrolled to the end. A dark semi-transparent tint (not a solid-color
   mask) reads on top of ANY seller content color, light or dark -
   confirmed against a real white-background seller banner
   (/item/20350787) where a plain surface-color fade was invisible.
   Desktop/mouse also gets a visible thin scrollbar on the inner box,
   same reasoning + device as .auction-rail's own desktop override. */
.auction-description--has-hscroll:not(.auction-description--at-hscroll-end)::after {
    content: '';
    position: absolute;
    top: 1px;
    right: 1px;
    bottom: 1px;
    width: 2.2rem;
    border-radius: 0 var(--radius) var(--radius) 0;
    background: linear-gradient(to right, transparent, rgba(0, 0, 0, 0.16));
    pointer-events: none;
}

@media (hover: hover) and (pointer: fine) {
    .auction-description__scroll {
        scrollbar-width: thin;
        scrollbar-color: var(--egun-border) transparent;
    }

    .auction-description__scroll::-webkit-scrollbar {
        height: 8px;
    }

    .auction-description__scroll::-webkit-scrollbar-thumb {
        background: var(--egun-border);
        border-radius: 999px;
    }

    .auction-description__scroll::-webkit-scrollbar-track {
        background: transparent;
    }
}

/* !important: legacy's WYSIWYG editor commonly writes fixed px sizes as an
   inline style="width:...;height:...", e.g. a real listing found at
   /artikel/20340759 (style="width: 1200px; height: 581px"). max-width
   already overrides an inline `width` regardless of specificity (a
   guaranteed CSS behavior, no !important needed for that part) - but
   plain `height: auto` does NOT win against an inline `height` on the
   same property, so the image's width was shrinking while its height
   stayed literal, distorting/"squishing" it. !important forces both to
   actually apply. */
.auction-description img,
.auction-description video,
.auction-description iframe,
.auction-description table {
    max-width: 100% !important;
    height: auto !important;
}

/* Sellers also wrap content in a plain <div style="width:800px;..."> decor
   frame (real example, /item/20350787: a logo banner nested inside one) -
   not an img/table, so the rule above never touched it, and unlike a
   table a div has no structural min-content floor, so simply capping its
   max-width is enough to make it (and the now-proportionally-scaled img
   inside it) actually fit the viewport instead of relying on the
   description's own horizontal scroll for content that didn't need to
   scroll at all (user report 2026-07-20: still looked "broken" even with
   the scroll-shadow hint in place - shrinking beats scrolling whenever
   shrinking is possible). max-width wins over an inline `width` regardless
   of specificity (see the note above) - !important only for cases where
   something more specific overrides max-width itself. */
.auction-description div {
    max-width: 100% !important;
}

/* Sellers wrap their descriptions in decorative fixed-width table frames
   (real example, /item/20411546: nested <table width="1321"> holding
   1281px-wide images). max-width alone CANNOT fix that: a table never
   shrinks below its minimum content width, and an image's percentage
   max-width inside an auto-layout table resolves circularly against a
   cell that is itself sized from the image's specified width - so the
   whole frame rendered ~1340px wide and forced sideways scrolling
   through the entire description. Flattening every seller table to
   block flow dissolves the frames entirely: images become normal block
   content (max-width:100% now actually applies), text wraps at the
   viewport, nothing scrolls. Genuinely tabular seller content stacks
   its cells vertically instead - on a phone that beats a 3x-viewport
   sideways scroll. (Legacy's own mobile view sidesteps this by putting
   the description in an iframe the user pans around in - strictly worse
   UX than reflowing.) */
.auction-description table,
.auction-description thead,
.auction-description tbody,
.auction-description tfoot,
.auction-description tr,
.auction-description th,
.auction-description td {
    display: block;
    width: auto !important;
    /* Fixed heights must fall with the table layout they came from: a
       flattened <td height="197"> (or inline style="height:431px") whose
       content is TALLER keeps its box at the fixed height as a block, so
       the overflowing text paints straight over the following block -
       the "text over text" glitch on /item/19999981. */
    height: auto !important;
}

/* Same WYSIWYG exports also nest <blockquote> levels for indentation
   (real example, /item/20391896: 3 levels deep = 240px of default
   margins, leaving an 84px text column on a phone) - flatten them like
   the tables above. And their decorative cell background= textures
   (flattened to blocks above, they tile as odd vertical strips; the
   URLs are http:// and mixed-content-blocked on https anyway). */
.auction-description blockquote {
    margin: 0 !important;
    padding: 0 !important;
}

.auction-description [background] {
    background-image: none !important;
}

/* ...except this app's OWN appended markup: the category-disclosure
   block (ListingCreationService::buildDescription() appends it) uses
   small label/value tables that never overflow - keep those real tables
   so the two columns stay aligned. */
.auction-description .category-disclosure table { display: table; }
.auction-description .category-disclosure tr { display: table-row; }
.auction-description .category-disclosure th,
.auction-description .category-disclosure td { display: table-cell; width: auto !important; }

/* Collapsed to ~5 lines by default (a seller's AGB text can be arbitrarily
   long) - JS in _agb.html.twig only reveals the toggle button when the
   text actually overflows this height, and adds --expanded on click. */
/* Ports the legacy away-message banner's own highlighting intent
   (paintContentBox(..., 'red', ...)) - a notice, not just info, so it
   gets a distinguishing accent unlike the plain .auction-description box
   .auction-agb reuses as-is. */
.auction-away {
    border-color: #c0392b;
    border-left: 4px solid #c0392b;
}

/* Decorative-only "Meine Kunden" blacklist flag - ports legacy's own
   `black` indicator, no click-through action there either. */
.contact-history-list {
    width: 100%;
    /* separate+0, not collapse - border-radius doesn't clip collapsed
       table borders in most engines. */
    border-collapse: separate;
    border-spacing: 0;
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    overflow: hidden;
    margin-bottom: 1rem;
}

.contact-history-list th {
    text-align: left;
    font-size: 0.85rem;
    color: var(--egun-text-muted);
    padding: 0.6rem 0.8rem;
    border-bottom: 1px solid var(--egun-border);
}

.contact-history-list td {
    padding: 0.6rem 0.8rem;
    border-bottom: 1px solid var(--egun-border);
}

.contact-history-list tbody tr:last-child td {
    border-bottom: none;
}

/* Customer detail: unbilled-deal picker + invoice cards */

.customer-detail-deals {
    list-style: none;
    margin: 0;
    padding: 0;
    flex: 1 1 100%;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}

.customer-detail-deals li {
    background: var(--egun-bg);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.45rem 0.6rem;
}

.customer-detail-deals label {
    margin: 0;
    font-weight: 400;
}

.invoice-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.8rem;
}

.invoice-card {
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.7rem 0.8rem;
}

.invoice-card__head {
    margin: 0;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

.invoice-card__number {
    font-weight: 600;
}

.invoice-card__meta {
    margin: 0.2rem 0 0;
    display: flex;
    flex-wrap: wrap;
    gap: 0.2rem 1rem;
    font-size: 0.9rem;
    color: var(--egun-text-muted);
}

.invoice-card__form {
    margin-top: 0.7rem;
    padding-top: 0.7rem;
    border-top: 1px solid var(--egun-border);
}

.invoice-card__form form {
    margin-bottom: 0;
}

.invoice-card__form input,
.invoice-card__form textarea {
    background: var(--egun-bg);
}

.invoice-card__notes {
    margin: 0.6rem 0 0;
    padding-left: 1.1rem;
    font-size: 0.9rem;
}

.customer-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.customer-card {
    display: block;
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.7rem 0.8rem;
    color: var(--egun-text);
    text-decoration: none;
}

.customer-card:hover {
    text-decoration: none;
    border-color: var(--egun-blue);
}

.customer-card__nick {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-weight: 600;
    color: var(--egun-blue);
    margin-bottom: 0.4rem;
}

.customer-card__figures {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem 1.5rem;
    font-size: 0.9rem;
}

.customer-card__figure {
    display: flex;
    flex-direction: column;
}

.customer-card__figure-label {
    font-size: 0.8rem;
    color: var(--egun-text-muted);
}

.auction-agb__text {
    max-height: 7.5em;
    overflow: hidden;
}

.auction-agb__text--expanded {
    max-height: none;
}

.auction-agb__toggle {
    margin-top: 0.6rem;
}

/* --- Footer / help pages --- */

.site-footer {
    margin-top: 2rem;
    padding: 1rem;
    text-align: center;
    border-top: 1px solid var(--egun-border);
    font-size: 0.8rem;
    color: var(--egun-text-muted);
}

.site-footer__links {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.4rem 0.8rem;
    margin-bottom: 0.6rem;
}

/* "Zur klassischen Ansicht" is a POST form (prefetch must not be able
   to trigger the year-long opt-out, 2026-08-18) but has to sit in the
   link row as if it were one of the links. */
.site-footer__optout {
    display: inline;
}

.site-footer__optout button {
    padding: 0;
    border: 0;
    background: none;
    font: inherit;
    color: var(--egun-blue); /* same as the sibling <a>s (global `a` rule) */
    text-decoration: none;
    cursor: pointer;
}

.help-content {
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.9rem 1rem;
    /* Long legal prose (AGB/Datenschutz) reads as a set block
       (user request 2026-07-17); hyphens keep justified German from
       developing rivers on narrow screens. */
    text-align: justify;
    hyphens: auto;
}

/* The Impressum block (rendered from HelpController's transcription of
   legacy's Impressum.gif) - centered like the original image, the
   Haftungshinweis as quiet prose. */
/* App-help header: title left, "eGun kontaktieren" pill right. */
.app-help__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
    flex-wrap: wrap;
}

/* Kontakt help page: label line + pill row per recipient - stacked so
   long translated labels never fight the pills for width. */
.contact-help__row {
    margin-bottom: 1.1rem;
    text-align: left;
}

.contact-help__row:last-child {
    margin-bottom: 0.2rem;
}

.contact-help__label {
    margin: 0 0 0.35rem;
    font-weight: 600;
}

.contact-help__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0;
}

.impressum-text {
    text-align: center;
}

.impressum-text__logo {
    display: block;
    height: 44px;
    margin: 0.3rem auto 0.5rem;
}

.impressum-text__tagline {
    font-family: var(--font-display);
    font-weight: 600;
    letter-spacing: 0.02em;
}

.impressum-text__note {
    margin-top: 1.2rem;
    text-align: justify;
    font-size: 0.9rem;
    color: var(--egun-text-muted);
}

/* Shared "current filter" link styling - feedback's sign filter, and
   My Purchases'/My Sales' day filter, all use this same
   BEM-ish `__filter--active` class naming per row type. */
.feedback-list__filter--active,
.my-purchase-list__filter--active,
.my-sales-list__filter--active {
    font-weight: 700;
    text-decoration: underline;
}

/* Positive-feedback share next to the rating count on the item page. */
.seller-positive-pct {
    margin-left: 0.4rem;
    padding: 0.1rem 0.55rem;
    border-radius: 999px;
    background: #e6f4ea;
    color: #1a7a35;
    font-size: 0.85rem;
    font-weight: 600;
    white-space: nowrap;
}

/* On the item page the chip and the (score) are LINKS to the seller's
   rating page - keep the chip's green (not link blue), no underline. */
a.seller-positive-pct,
a.seller-positive-pct:hover {
    color: #1a7a35;
    text-decoration: none;
}

.auction-seller__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.6rem;
}

.auction-seller__head h2 {
    margin: 0 0 0.5rem;
}

.auction-seller__identity {
    margin-bottom: 0.15rem;
}

.auction-seller__pct-line {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0;
}

.auction-seller__pct-line .seller-positive-pct {
    margin-left: 0;
}

/* --- Mein Konto --- */

.totp-setup {
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 1rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.totp-setup__qr {
    align-self: center;
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
}

.totp-setup__key {
    width: 100%;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.9rem;
    background: var(--egun-bg);
}

.totp-setup label {
    font-weight: 600;
}

/* 2FA state (2026-07-19): unmissable red/green status pill, same
   dot-plus-tint vocabulary as the bid-standing banner. */
.totp-state {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.35rem 0.7rem;
    border-radius: 999px;
    font-weight: 600;
    font-size: 0.92rem;
}

.totp-state::before {
    content: '';
    flex: 0 0 auto;
    width: 0.6rem;
    height: 0.6rem;
    border-radius: 50%;
    background: currentColor;
}

.totp-state--on {
    background: #e6f4ea;
    color: #1a7a35;
}

.totp-state--off {
    background: #fdecea;
    color: #b3261e;
}

.profile-hint {
    flex: 1 1 100%;
    margin: 0;
    color: var(--egun-text-muted);
}

/* Breathing room between the E-Mail/2FA sections and the Adressdaten
   card that follows them. */
.profile-section {
    margin-bottom: 1rem;
}

/* --- Push-Benachrichtigungen (Einstellungen) --- */

.push-settings__intro,
.push-settings__hint {
    margin: 0;
    color: var(--egun-text-muted);
    font-size: 0.9rem;
}

.push-settings__status {
    margin: 0;
    font-weight: 600;
}

.push-settings__options {
    flex: 1 1 100%;
    margin-top: 0.4rem;
    padding-top: 0.6rem;
    border-top: 1px solid var(--egun-border);
}

.push-settings__options-caption {
    margin: 0;
    font-weight: 600;
    font-size: 0.9rem;
}

.push-settings__options-note {
    margin: 0;
    color: var(--feedback-positive);
}

/* --- Gespeicherte Suchen --- */

.saved-search-push-note {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-left: 4px solid var(--egun-gold);
    border-radius: var(--radius);
    padding: 0.7rem 0.8rem;
    margin-bottom: 1rem;
    font-size: 0.9rem;
}

.saved-search-push-note__icon {
    font-size: 1.1rem;
    flex: 0 0 auto;
}

.saved-search-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.saved-search-row {
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.7rem 0.8rem;
}

.saved-search-row__link {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    color: var(--egun-text);
    text-decoration: none;
    margin-bottom: 0.5rem;
}

.saved-search-row__icon {
    width: 1.2rem;
    height: 1.2rem;
    flex: 0 0 auto;
    color: var(--egun-text-muted);
}

.saved-search-row__body {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
}

.saved-search-row__label {
    font-weight: 600;
    color: var(--egun-blue);
    overflow-wrap: anywhere;
}

.saved-search-row__date {
    font-size: 0.8rem;
    color: var(--egun-text-muted);
}

/* --- Meine Bewertungen --- */

.rating-summary {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.8rem 1rem;
    margin-bottom: 1.2rem;
}

.rating-summary__head {
    display: flex;
    align-items: center;
    gap: 0.9rem;
}

.rating-summary__counts {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.rating-summary__count {
    padding: 0.15rem 0.6rem;
    border-radius: 999px;
    font-size: 0.85rem;
    font-weight: 600;
    border: 1px solid var(--egun-border);
    background: var(--egun-bg);
}

.rating-summary__count--positive { color: var(--feedback-positive); }
.rating-summary__count--neutral { color: var(--feedback-neutral); }
.rating-summary__count--negative { color: var(--feedback-negative); }

.rating-summary__link {
    font-size: 0.9rem;
    align-self: flex-start;
}

/* Eyebrows on this page carry the Community world dot (Bewertungen lives
   in the Community nav group - u = blue, same wordmark coding as the
   dashboard's group dots and the sell form's red Verkaufen dot). */
.rating-eyebrow {
    display: flex;
    align-items: center;
    gap: 0.45em;
}

.rating-eyebrow::before {
    content: '';
    flex: none;
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--egun-blue);
}

.rating-pending__title {
    margin: 1.4rem 0 0.6rem;
}

/* Generic gold count chip (same device as the dashboard/search chips):
   "how many need me?" at a glance. */
.count-chip {
    flex: none;
    min-width: 1.7em;
    padding: 0.18em 0.5em;
    border-radius: 999px;
    text-align: center;
    font-size: 0.85rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0;
    background: var(--egun-gold);
    color: #1a1a1a;
}

/* Proportional feedback strip: segment widths = share of positive/
   neutral/negative ratings (flex-grow carries the counts inline). */
.rating-ratio {
    display: flex;
    height: 6px;
    border-radius: 999px;
    overflow: hidden;
    background: var(--egun-bg);
}

.rating-ratio__seg {
    flex: 0 1 auto;
    flex-basis: 0;
    min-width: 6px;
}

.rating-ratio__seg--positive { background: var(--feedback-positive); }
.rating-ratio__seg--neutral { background: var(--feedback-neutral); }
.rating-ratio__seg--negative { background: var(--feedback-negative); }

.rating-summary__score {
    font-size: 1.9rem;
    font-weight: 700;
    color: var(--egun-blue);
    line-height: 1;
}

.rating-summary__caption {
    font-size: 0.9rem;
    color: var(--egun-text-muted);
    line-height: 1.5;
}

.rating-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.8rem;
}

.rating-list__row {
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.8rem;
}

.rating-list__head {
    margin: 0 0 0.6rem;
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}

.rating-list__item-link {
    font-weight: 600;
}

.rating-list__party {
    font-size: 0.9rem;
    color: var(--egun-text-muted);
}

.rating-list__form {
    margin-bottom: 0;
}

/* The positive/neutral/negative choice row - one pill per option, in the
   same green/grey/red the public feedback page uses for the matching
   signs, so the choice reads at a glance. */
.rating-list__choices {
    flex: 1 1 100%;
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.rating-list__choice {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    margin: 0;
    padding: 0.35rem 0.8rem;
    border: 1px solid var(--egun-border);
    border-radius: 999px;
    background: var(--egun-bg);
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
}

.rating-list__choice--positive { color: var(--feedback-positive); }
.rating-list__choice--neutral { color: var(--feedback-neutral); }
.rating-list__choice--negative { color: var(--feedback-negative); }

.rating-list__choice:has(input:checked) {
    border-width: 2px;
    padding: calc(0.35rem - 1px) calc(0.8rem - 1px);
}

.rating-list__choice--positive:has(input:checked) { border-color: var(--feedback-positive); background: #e6f4ea; }
.rating-list__choice--neutral:has(input:checked) { border-color: var(--feedback-neutral); background: #eef0f3; }
.rating-list__choice--negative:has(input:checked) { border-color: var(--feedback-negative); background: #fdecea; }

.rating-list__comment-label {
    flex: 1 1 100%;
    font-size: 0.9rem;
    margin: 0.3rem 0 0;
}

.rating-list__form textarea {
    background: var(--egun-bg);
}

.rating-list__form button[type="submit"] {
    margin-left: auto;
}

/* --- Meine Angebote --- */

.my-listings-list {
    list-style: none;
    margin: 0 0 1rem;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.8rem;
}

.my-listings-row {
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.8rem;
}

.my-listings-row__stats {
    margin: 0.5rem 0 0;
    font-size: 0.85rem;
    color: var(--egun-text-muted);
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.3rem 0.6rem;
}

.my-listings-row__descr-fields {
    margin-top: 0.7rem;
    padding-top: 0.7rem;
    border-top: 1px solid var(--egun-border);
}

.my-listings-row__descr-fields form {
    margin-bottom: 0;
}

.my-listings-row__descr-fields textarea,
.my-listings-row__descr-fields select {
    background: var(--egun-bg);
}

/* --- Ersatzkäufer-Angebote --- */

.runner-up-offer-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.runner-up-offer-row {
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.7rem 0.8rem;
}

.runner-up-offer-row__link {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    color: var(--egun-text);
    text-decoration: none;
}

.runner-up-offer-row__title {
    font-weight: 600;
    color: var(--egun-blue);
}

.runner-up-offer-row__meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.2rem 0.8rem;
    font-size: 0.85rem;
    color: var(--egun-text-muted);
}

/* --- Widerrufsanfragen --- */

.revoke-request-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.revoke-request-row {
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.7rem 0.8rem;
}

.revoke-request-row--accepted,
.revoke-request-row--rejected {
    opacity: 0.75;
}

.revoke-request-row__link {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    color: var(--egun-text);
    text-decoration: none;
    margin-bottom: 0.5rem;
}

.revoke-request-row__title {
    font-weight: 600;
}

.revoke-request-row__meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.2rem 0.8rem;
    font-size: 0.85rem;
    color: var(--egun-text-muted);
}

.revoke-request-row__actions {
    display: flex;
    gap: 0.5rem;
}

.revoke-request-row__actions form {
    margin: 0;
}

.revoke-request-row__state {
    display: inline-block;
    padding: 0.15rem 0.6rem;
    border-radius: 999px;
    font-size: 0.8rem;
    font-weight: 700;
    text-transform: uppercase;
    color: #fff;
}

.revoke-request-row__state--accepted { background: var(--feedback-positive); }
.revoke-request-row__state--rejected { background: var(--feedback-negative); }

/* --- Meine Verkäufe --- */

/* Header: h1 + the generic gold count chip. */
.my-sales-head {
    display: flex;
    align-items: center;
    gap: 0.6rem;
}

.my-sales-head h1 {
    margin: 0;
}

/* One toolbar row: day-range chips (search-toolbar .sort-chip device)
   + the status select, wrapping on narrow screens. */
.my-sales-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.45rem;
    margin: 0.8rem 0 1rem;
}

.my-sales-toolbar__status {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    margin: 0 0 0 auto;
}

.my-sales-toolbar__status label {
    margin: 0;
    font-weight: 600;
    font-size: 0.9rem;
}

.my-sales-toolbar__status select {
    flex: 0 1 12rem;
    padding: 0.35rem 0.5rem;
}

/* The Abwicklung step track: Bezahlt → Versendet as two joined state
   chips per buyer. Single quantity: the chips ARE the checkboxes
   (choice-pills convention: native input stays visible) and auto-save.
   Multi quantity: static x-of-n chips as a <details> summary opening
   the count editor. done = green, part = gold, open = plain surface. */
.fulfill {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    margin: 0.55rem 0 0.2rem;
}

form.fulfill {
    margin-bottom: 0.2rem;
}

.fulfill-step {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    margin: 0;
    padding: 0.32rem 0.75rem;
    border: 1px solid var(--egun-border);
    border-radius: 999px;
    background: var(--egun-surface);
    font-size: 0.9rem;
    font-weight: 600;
    line-height: 1.2;
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease;
}

.fulfill-step input[type="checkbox"] {
    margin: 0;
    accent-color: var(--egun-green);
}

.fulfill-step--static {
    cursor: pointer;
    font-weight: 500;
}

.fulfill-step--done {
    background: color-mix(in srgb, var(--egun-green) 14%, var(--egun-surface));
    border-color: color-mix(in srgb, var(--egun-green) 55%, var(--egun-border));
    color: var(--egun-green);
}

.fulfill-step--part {
    background: color-mix(in srgb, var(--egun-gold) 22%, var(--egun-surface));
    border-color: color-mix(in srgb, var(--egun-gold) 70%, var(--egun-border));
}

.fulfill-step:has(input:focus-visible) {
    outline: 2px solid var(--egun-blue);
    outline-offset: 2px;
}

/* The joint between the two steps - the sequence made visible. */
.fulfill-joint {
    flex: 0 0 1rem;
    height: 2px;
    background: var(--egun-border);
}

.fulfill--auto noscript button {
    margin-left: 0.5rem;
}

.fulfill-editor summary.fulfill {
    list-style: none;
}

.fulfill-editor summary.fulfill::-webkit-details-marker {
    display: none;
}

.fulfill-editor__chevron {
    margin-left: 0.35rem;
    color: var(--egun-text-muted);
    font-size: 0.8rem;
    transition: transform 0.15s ease;
}

.fulfill-editor[open] .fulfill-editor__chevron {
    transform: rotate(180deg);
}

.fulfill-editor[open] summary.fulfill {
    margin-bottom: 0.4rem;
}

/* Escalation actions - the one block on the page allowed to shout. */
.buyer-alert {
    margin: 0.5rem 0;
    padding: 0.5rem 0.6rem;
    border-left: 3px solid var(--egun-gold);
    border-radius: 0 4px 4px 0;
    background: rgba(255, 204, 51, 0.13);
}

/* § 25 PStTG selling block (2026-08-06): the site-wide notice for a
   reportable seller without tax data. Same gold attention device as
   .buyer-alert - it may shout, but in the house voice. */
.tax-block-banner {
    margin: 0 0 0.9rem;
    padding: 0.6rem 0.75rem;
    border-left: 3px solid var(--egun-gold);
    border-radius: 0 4px 4px 0;
    background: rgba(255, 204, 51, 0.13);
}

.tax-block-banner p {
    margin: 0 0 0.45rem;
    font-size: 0.9rem;
}

.tax-block-banner__action {
    display: inline-block;
    font-weight: 600;
}

/* The dismissible nag variant: same gold surface (one attention idiom,
   two severities), link + snooze side by side. */
.tax-block-banner__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem 1rem;
}

.tax-block-banner__actions form {
    margin: 0;
}

.my-sales-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.8rem;
}

.my-sales-row {
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.8rem;
}

.my-sales-row__title {
    margin: 0 0 0.15rem;
    font-weight: 600;
}

/* Thumb + title/meta head (2026-08-06): same 64px visual as
   .list-item__thumb so my-sales reads like the search cards. */
.my-sales-row__head {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
}

.my-sales-row__head-body {
    flex: 1 1 auto;
    min-width: 0;
}

.my-sales-row__thumb {
    flex: 0 0 auto;
    width: 64px;
    height: 64px;
    border-radius: 6px;
    overflow: hidden;
    background: var(--egun-bg);
    display: flex;
    align-items: center;
    justify-content: center;
}

.my-sales-row__thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    overflow: hidden;
    font-size: 0.55rem;
    line-height: 1.1;
    color: var(--egun-text-muted);
}

/* One meta line: money leads in the display face (list-item__price
   device), date and Artikel-ID quiet beside it. */
.my-sales-row__meta-line {
    margin: 0 0 0.6rem;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.15rem 0.9rem;
    font-size: 0.85rem;
    color: var(--egun-text-muted);
}

.my-sales-row__price {
    font-family: var(--font-display), system-ui, sans-serif;
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--egun-text);
}

/* Rare bookkeeping toggle, footer position. */
.my-sales-row__resold-form {
    margin: 0.45rem 0 0;
}

.my-sales-row__buyers {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.my-sales-buyer-row {
    background: var(--egun-bg);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.6rem 0.7rem;
}

.my-sales-buyer-row__head {
    margin: 0 0 0.5rem;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.3rem 0.7rem;
}

.my-sales-buyer-row__reminder-actions {
    margin: 0 0 0.6rem;
}

.my-sales-buyer-row__counts-form {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    margin: 0 0 0.5rem;
    font-size: 0.9rem;
}

.my-sales-buyer-row__counts-form label {
    margin: 0;
    font-weight: 600;
}

.my-sales-buyer-row__counts-form input[type="number"] {
    flex: 0 0 4rem;
    background: var(--egun-surface);
}

.my-sales-buyer-row__link {
    font-size: 0.9rem;
    padding: 0.3rem 0.2rem;
}

.my-sales-buyer-row .row-actions {
    margin-top: 0;
}

.my-sales-buyer-row__note-fields {
    margin-top: 0.6rem;
    padding-top: 0.6rem;
    border-top: 1px solid var(--egun-border);
}

.my-sales-buyer-row__note-fields form {
    margin-bottom: 0;
}

.my-sales-buyer-row__note-fields textarea {
    background: var(--egun-surface);
}

/* --- Public feedback history (/member/{nick}/feedback) --- */

/* Sign colors match legacy user_feedbacks.php exactly: 'Lob' #0A0,
   'Beschwerde' red (tpl/wm.user_feedbacks.php:58-59), neutral plain/grey. */
:root {
    --feedback-positive: #0a0;
    --feedback-negative: #d00;
    --feedback-neutral: #777;
}

.feedback-summary {
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.8rem;
    margin-bottom: 1rem;
}

.feedback-summary-grid {
    width: 100%;
    border-collapse: collapse;
    /* Compact enough that the table's MIN-CONTENT width fits a narrow
       phone's card - at 0.95rem/0.5rem padding it silently spilled into
       the card padding at 390px and clipped past the card edge on 360px
       devices ("Negativ" cut off, user-reported), which also read as
       off-center. */
    font-size: 0.85rem;
}

.feedback-summary-grid th,
.feedback-summary-grid td {
    padding: 0.35rem 0.3rem;
    text-align: center;
    border-bottom: 1px solid var(--egun-border);
}

.feedback-summary-grid tbody tr:last-child td {
    border-bottom: none;
}

.feedback-summary-grid__label {
    text-align: left;
    font-weight: 600;
    /* no nowrap: "Letztes Halbjahr" may wrap on very small screens
       rather than force the table wider than its card */
}

.feedback-summary-grid__head--positive { color: var(--feedback-positive); }
.feedback-summary-grid__head--neutral { color: var(--feedback-neutral); }
.feedback-summary-grid__head--negative { color: var(--feedback-negative); }

.feedback-summary-grid__cell a {
    text-decoration: none;
    font-weight: 600;
}

.feedback-summary-grid__cell--positive a { color: var(--feedback-positive); }
.feedback-summary-grid__cell--neutral a { color: var(--feedback-neutral); }
.feedback-summary-grid__cell--negative a { color: var(--feedback-negative); }

.feedback-summary__hint {
    margin: 0.4rem 0 0;
    color: var(--egun-text-muted);
    text-align: right;
}

/* "Zurückgezogene Gebote" (legacy fakebids counter): same quiet footnote
   placement as the hint above, but it turns warning-red as soon as the
   counter is non-zero - the number is the warning. */
.feedback-summary__retracted { margin: 0.25rem 0 0; font-size: 0.85rem; color: var(--egun-text-muted); }
.feedback-summary__retracted--warn { color: var(--feedback-negative); font-weight: 600; }

.feedback-list__filters {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.feedback-filter {
    display: inline-block;
    padding: 0.3rem 0.8rem;
    border: 1px solid var(--egun-border);
    border-radius: 999px;
    background: var(--egun-surface);
    color: var(--egun-text);
    text-decoration: none;
    font-size: 0.9rem;
}

.feedback-filter--positive { color: var(--feedback-positive); }
.feedback-filter--neutral { color: var(--feedback-neutral); }
.feedback-filter--negative { color: var(--feedback-negative); }

.feedback-filter--active {
    border-color: currentColor;
    font-weight: 700;
}

.feedback-list {
    list-style: none;
    margin: 1rem 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.feedback-list__row {
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-left-width: 4px;
    border-radius: var(--radius);
    padding: 0.7rem 0.8rem;
}

.feedback-list__row--positive { border-left-color: var(--feedback-positive); }
.feedback-list__row--neutral { border-left-color: var(--feedback-neutral); }
.feedback-list__row--negative { border-left-color: var(--feedback-negative); }

/* The rated auction's title on its own line under the meta row - one
   line, ellipsized, never wrapping. */
.feedback-list__auction-line {
    margin: -0.2rem 0 0.4rem;
    font-size: 0.85rem;
}

.feedback-list__auction {
    display: block;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.feedback-list__meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.3rem 0.7rem;
    margin: 0 0 0.4rem;
    font-size: 0.85rem;
    color: var(--egun-text-muted);
}

.feedback-list__meta strong {
    color: var(--egun-text);
}

.feedback-badge {
    display: inline-block;
    padding: 0.1rem 0.55rem;
    border-radius: 999px;
    color: #fff;
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
}

.feedback-badge--positive { background: var(--feedback-positive); }
.feedback-badge--neutral { background: var(--feedback-neutral); }
.feedback-badge--negative { background: var(--feedback-negative); }

.feedback-list__comment {
    margin: 0;
    overflow-wrap: break-word;
}

.feedback-list__expired {
    font-style: italic;
}

.feedback-list__answer {
    margin: 0.5rem 0 0;
    padding: 0.4rem 0.6rem;
    background: var(--egun-bg);
    border-radius: var(--radius);
    font-size: 0.9rem;
    overflow-wrap: break-word;
}

.feedback-list__reply-form {
    margin: 0.5rem 0 0;
}

.feedback-list__reply-form label {
    font-weight: 600;
    flex: 1 1 100%;
}

/* --- My Bids / My Purchases --- */

.my-bid-list,
.my-purchase-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.my-bid-row,
.my-purchase-row {
    display: block;
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.6rem;
}

.my-bid-row__link,
.my-purchase-row__link {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    color: var(--egun-text);
    text-decoration: none;
}

.my-bid-row__title,
.my-purchase-row__title {
    font-weight: 600;
}

.my-bid-row__meta,
.my-purchase-row__meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1rem;
    font-size: 0.85rem;
    color: var(--egun-text-muted);
}

.my-bid-row__ends {
    margin-left: auto;
}

/* New card layout (shares the thumbnail/details classes with
   my-purchase-row): the status badge sizes to its text, the leading-
   bidder line and rebid button get breathing room. */
.my-bid-row .my-bid-row__status {
    align-self: flex-start;
}

.my-bid-row__leading {
    display: block;
    margin-top: 0.5rem;
    font-size: 0.9rem;
}

.my-bid-row__rebid-button {
    margin-top: 0.6rem;
}

.my-bid-row__status--winning {
    background: #e6f4ea;
    color: #1a7a35;
}

.my-bid-row__status--outbid {
    background: #fdecea;
    color: #b3261e;
}

.my-purchase-row__head {
    display: flex;
    gap: 0.7rem;
    align-items: flex-start;
    color: var(--egun-text);
    text-decoration: none;
}

.my-purchase-row__thumb {
    flex: 0 0 72px;
    width: 72px;
    height: 72px;
    border-radius: var(--radius);
    background: var(--egun-bg);
    border: 1px solid var(--egun-border);
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
}

.my-purchase-row__thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* "No photo" pictogram tone (2026-07-21) - quiet outline, clearly a
   placeholder, clearly not a broken image. */
.no-image-icon {
    color: var(--egun-text-muted);
    opacity: 0.45;
}

.my-purchase-row__headline {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 0;
}

.my-purchase-row__bought {
    font-size: 0.8rem;
    color: var(--egun-text-muted);
}

.my-purchase-row__total {
    font-weight: 700;
    font-size: 1.05rem;
}

.my-purchase-row__details {
    margin: 0.6rem 0 0;
    padding: 0.5rem 0.7rem;
    background: var(--egun-bg);
    border-radius: var(--radius);
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.35rem 1rem;
    font-size: 0.85rem;
}

.my-purchase-row__details div {
    display: flex;
    flex-direction: column;
}

.my-purchase-row__details dt {
    color: var(--egun-text-muted);
    font-size: 0.75rem;
}

.my-purchase-row__details dd {
    margin: 0;
    overflow-wrap: anywhere;
}

.my-purchase-row__status {
    margin: 0.5rem 0 0;
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
}

.my-purchase-row__remind-form {
    margin: 0.6rem 0 0;
    align-items: center;
    gap: 0.4rem;
}

.my-purchase-row__remind-form select {
    flex: 0 1 16rem;
    font-size: 0.9rem;
    padding: 0.3rem 0.5rem;
}

.my-purchase-row__links {
    margin: 0.6rem 0 0;
    font-size: 0.9rem;
}

.my-purchase-row__note-fields {
    margin-top: 0.6rem;
    padding-top: 0.6rem;
    border-top: 1px solid var(--egun-border);
}

.my-purchase-row__note-fields form {
    margin-bottom: 0;
}

.my-purchase-row__note-fields textarea {
    background: var(--egun-bg);
}

.cafe-post {
    border: 1px solid var(--egun-border);
    border-radius: 4px;
    padding: 0.75rem 1rem;
    margin-bottom: 0.75rem;
}

.cafe-post__meta {
    font-size: 0.85rem;
    color: var(--egun-text-muted);
    margin-bottom: 0.5rem;
}

.cafe-post__text {
    white-space: pre-wrap;
}

.my-listings-edit__current-image {
    display: block;
    max-height: 150px;
    max-width: 100%;
    margin-bottom: 0.5rem;
}

.deal-mail-archive__meta {
    margin-bottom: 1.5rem;
}

.deal-mail-archive__entry {
    border: 1px solid var(--egun-border);
    border-radius: 4px;
    padding: 0.5rem 0.75rem;
    margin-bottom: 0.5rem;
}

.deal-mail-archive__entry summary {
    cursor: pointer;
    font-weight: bold;
}

.deal-mail-archive__body {
    white-space: pre-wrap;
    font-family: inherit;
    margin: 0.5rem 0 0;
}

.search-form__advanced {
    flex-basis: 100%;
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.5rem 0.75rem;
    background: var(--egun-surface);
}

.search-form__advanced summary {
    cursor: pointer;
    font-weight: 600;
}

.search-form__advanced fieldset {
    border: none;
    padding: 0;
    margin: 0.5rem 0;
}

.search-form__advanced legend {
    font-size: 0.85rem;
    color: var(--egun-text-muted);
    padding: 0;
}

.search-form__advanced label {
    display: inline-flex;
    margin-right: 0.75rem;
}

/* --- Search page: attached search bar + results sort toolbar --- */

/* Input and submit fused into one control - the query field is the page's
   one primary action, everything else on the page is secondary to it. */
.search-bar {
    display: flex;
    flex: 1 1 100%;
}

.search-bar input {
    flex: 1 1 auto;
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
    border-right: none;
}

.search-bar button {
    flex: none;
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
}

/* The fused input+button is ONE control, so the focus ring wraps the
   whole bar - the input's own ring ran flush into the button (user
   report 2026-07-20). Text inputs match :focus-visible on pointer
   clicks too, hence the :has() mirror of the global ring. */
.search-bar:has(input:focus-visible) {
    outline: 2px solid var(--egun-blue);
    outline-offset: 2px;
    border-radius: var(--radius);
}

.search-bar input:focus-visible {
    outline: none;
}

/* Autocomplete dropdown under the search bar: recent queries (buttons
   that resubmit) + matching category links, filtered client-side. */
.search-bar-wrap {
    position: relative;
    flex: 1 1 100%;
}

.search-suggest {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 30;
    margin-top: 0.2rem;
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    box-shadow: 0 6px 18px rgba(0, 0, 0, 0.12);
    overflow: hidden;
}

.search-suggest__head {
    padding: 0.4rem 0.75rem 0.15rem;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--egun-text-muted);
}

.search-suggest__item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    width: 100%;
    padding: 0.45rem 0.75rem;
    border: none;
    border-radius: 0;
    background: none;
    color: var(--egun-text);
    font-size: 0.95rem;
    font-weight: 400;
    text-align: left;
    text-decoration: none;
    cursor: pointer;
}

.search-suggest__item:hover {
    background: var(--egun-bg);
    color: var(--egun-text);
}

.search-suggest__chip {
    flex: none;
    font-size: 0.72rem;
    padding: 0.1em 0.5em;
    border-radius: 999px;
    border: 1px solid var(--egun-border);
    color: var(--egun-text-muted);
}

/* "Ähnliche Artikel" on the item page. */
.similar-items {
    margin-top: 1.2rem;
}

/* "Zuletzt angesehen" tiles reuse .list-item; the anchor itself is the row. */
.recent-item {
    color: var(--egun-text);
    text-decoration: none;
}

/* --- Bottom tab bar --- */

:root {
    --tab-bar-h: 3.55rem;
}

body {
    /* content must never hide behind the fixed tab bar */
    padding-bottom: calc(var(--tab-bar-h) + env(safe-area-inset-bottom, 0px));
}

.tab-bar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 80;
    display: flex;
    background: var(--egun-surface);
    border-top: 1px solid var(--egun-border);
    padding-bottom: env(safe-area-inset-bottom, 0px);
}

.tab-bar__item {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    gap: 2px;
    padding: 0.4rem 0.1rem 0.3rem;
    min-height: 44px;
    font-size: 0.62rem;
    line-height: 1.1;
    color: var(--egun-text-muted);
    text-decoration: none;
    text-align: center;
}

.tab-bar__item:hover {
    text-decoration: none;
    color: var(--egun-text);
}

.tab-bar__item svg {
    width: 22px;
    height: 22px;
    flex: none;
}

.tab-bar__item span:last-child {
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.tab-bar__item--active {
    color: var(--egun-blue);
    font-weight: 600;
}

/* Red "needs my answer" counter, upper right of the Mein-eGun tab. */
.tab-bar__item {
    position: relative;
}

.tab-bar__badge {
    position: absolute;
    top: 2px;
    right: calc(50% - 24px);
    min-width: 1.15rem;
    padding: 0.05em 0.3em;
    border-radius: 999px;
    background: var(--egun-red);
    color: #fff;
    font-size: 0.68rem;
    font-weight: 700;
    line-height: 1.3;
    text-align: center;
    font-variant-numeric: tabular-nums;
}

/* Same counter on the matching dashboard tiles. */
.dashboard-tile {
    position: relative;
}

.dashboard-tile__badge {
    /* Inside the tile corner - hanging outside gets clipped by the
       tiles' rounded/clipped boxes. */
    position: absolute;
    top: 0.3rem;
    right: 0.35rem;
    min-width: 1.25rem;
    padding: 0.08em 0.35em;
    border-radius: 999px;
    background: var(--egun-red);
    color: #fff;
    font-size: 0.72rem;
    font-weight: 700;
    line-height: 1.35;
    text-align: center;
    font-variant-numeric: tabular-nums;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
}

/* The Verkaufen slot: raised gold circle, the marketplace CTA. */
.tab-bar__sell-badge {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 42px;
    height: 42px;
    margin-top: -16px;
    border-radius: 50%;
    background: var(--egun-gold);
    color: #1a1a1a;
    border: 3px solid var(--egun-surface);
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}

.tab-bar__sell-badge svg {
    width: 20px;
    height: 20px;
}

.tab-bar__item--sell,
.tab-bar__item--sell.tab-bar__item--active {
    color: var(--egun-text);
}

/* Fixed bottom elements sit ABOVE the tab bar now. */
.pwa-install-banner {
    bottom: calc(var(--tab-bar-h) + 0.6rem + env(safe-area-inset-bottom, 0px));
}

/* Emphasized "Alle Funktionen" row in the slimmed burger menu. */
.site-header__links-all {
    font-weight: 700;
    border-top: 1px solid var(--egun-border);
    margin-top: 0.3rem;
    padding-top: 0.55rem;
}

/* --- Verkäufer-Statistik --- */

.stats-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(105px, 1fr));
    gap: 0.6rem;
}

.stats-tile {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.7rem 0.8rem;
}

.stats-tile__value {
    font-family: var(--font-display);
    font-size: 1.5rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.stats-tile__label {
    font-size: 0.8rem;
    color: var(--egun-text-muted);
}

.stats-note {
    margin-top: 0.6rem;
    color: var(--egun-text-muted);
}

/* --- Kontoauszug --- */

.statement-section {
    margin-bottom: 1.4rem;
}

.statement-saldo {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0.4rem 0 0.8rem;
}

.statement-saldo__pill {
    padding: 0.25em 0.75em;
    border-radius: 999px;
    font-weight: 700;
}

.statement-saldo__pill--soll { background: #fdecea; color: #b3261e; }
.statement-saldo__pill--haben { background: #e6f4ea; color: #1e7e34; }

.statement-saldo__rabatt {
    font-size: 0.85rem;
    color: var(--egun-text-muted);
}

.statement-scroll {
    overflow-x: auto;
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
}

.statement-table {
    width: 100%;
    border-collapse: collapse;
    /* compact enough that Datum/Artikel/Beschreibung/Betrag fit a narrow
       phone WITHOUT clipping the Betrag column (audit #9) */
    font-size: 0.8rem;
}

.statement-table th,
.statement-table td {
    padding: 0.4rem 0.3rem;
    text-align: left;
    border-bottom: 1px solid var(--egun-border);
    vertical-align: top;
    hyphens: auto;
}

.statement-table td:last-child,
.statement-table th:last-child {
    text-align: right;
    white-space: nowrap;
}

.statement-table thead th {
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--egun-text-muted);
}

.statement-table tfoot td {
    font-weight: 700;
    border-bottom: none;
}

.statement-table__value {
    text-align: right;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
}

.statement-table__value--charge { color: var(--egun-red); }

.statement-invoices {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.statement-invoice {
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.6rem 0.75rem;
}

.statement-invoice__head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.5rem;
}

.statement-invoice__amount {
    font-variant-numeric: tabular-nums;
    font-weight: 600;
}

.statement-invoice__amount--open { color: var(--egun-red); }

.statement-invoice__meta {
    margin-top: 0.2rem;
    font-size: 0.85rem;
    color: var(--egun-text-muted);
}

/* Preis von / bis / PLZ side by side with their caption above - three
   loose placeholder-only inputs were the old form's main untidiness. */
.filter-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0.5rem;
    width: 100%;
}

.search-form__advanced .filter-grid label {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: 0.25rem;
    margin-right: 0;
    font-size: 0.85rem;
    color: var(--egun-text-muted);
}

/* A one-third cell clips option texts like "+ 100 km" - the Umkreis
   select (and any future select-bearing cell) gets two thirds. */
.filter-grid__wide {
    grid-column: span 2;
}

/* Result toolbar: gold count chip (same device as the dashboard's count
   chips) + a WRAPPING sort-chip row. The active chip shows the current
   direction; tapping it again flips asc/desc.
   scroll-margin-top: the toolbar is the #search-results anchor the form
   submits to - without the margin, the sticky .site-header covers it. */
.search-toolbar {
    scroll-margin-top: 4rem;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 0.8rem;
}

.search-toolbar__count {
    flex: none;
    padding: 0.18em 0.6em;
    border-radius: 999px;
    background: var(--egun-gold);
    color: #1a1a1a;
    font-size: 0.85rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.search-toolbar__sort {
    display: flex;
    /* WRAP instead of a horizontal scroll rail (user decision
       2026-07-18: sort options must never require scrolling) - with
       four chips the row breaks into two visible lines when needed. */
    flex-wrap: wrap;
    gap: 0.4rem;
    flex: 1 1 auto;
    min-width: 0;
}

.sort-chip {
    flex: none;
    padding: 0.5em 0.85em; /* UX audit N1: ~38px touch height (was 28px) */
    border: 1px solid var(--egun-border);
    border-radius: 999px;
    background: var(--egun-surface);
    color: var(--egun-text);
    font-size: 0.9rem;
    white-space: nowrap;
    text-decoration: none;
}

.sort-chip:hover {
    border-color: var(--egun-blue);
    color: var(--egun-blue);
    text-decoration: none;
}

.sort-chip--active,
.sort-chip--active:hover {
    background: var(--egun-blue);
    border-color: var(--egun-blue);
    color: #fff;
    font-weight: 600;
}

/* Inside the toolbar the save-search form is a plain inline item, not a
   block with the global form margin. */
.search-toolbar .save-search-form {
    margin: 0;
    flex: none;
}

/* Dashboard (Ihr persönlicher Bereich): quiet eyebrow typography, an
   action list whose count chips answer "how much needs me?" at a glance
   (gold = open action, red = complaint against me), and the four
   quick-access worlds each dotted in the color of "its" letter of the
   eGun wordmark (sampled from egun-logo.png: e=red, G=gold, u=blue,
   n=green) - the brand mark itself becomes the page's color system. */
.dashboard-hello {
    margin: 0.4rem 0 1.2rem;
}

.dashboard-eyebrow {
    margin: 0 0 0.45rem;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--egun-text-muted);
}

.dashboard-hello .dashboard-eyebrow {
    margin-bottom: 0.15rem;
}

.dashboard-hello__nick {
    margin: 0;
    font-size: 1.7rem;
    line-height: 1.15;
    color: var(--egun-blue);
    overflow-wrap: anywhere;
}

.dashboard-system-messages {
    margin-bottom: 1.4rem;
}

.dashboard-all-clear {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0;
    padding: 0.75rem 0.9rem;
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    color: var(--egun-text-muted);
}

.dashboard-all-clear::before {
    content: "\2713";
    font-weight: 700;
    color: var(--egun-green);
}

.dashboard-message-list {
    list-style: none;
    margin: 0;
    padding: 0;
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    overflow: hidden;
}

.dashboard-message-list li + li {
    border-top: 1px solid var(--egun-border);
}

.dashboard-message {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    padding: 0.7rem 0.8rem;
    color: var(--egun-text);
    text-decoration: none;
}

.dashboard-message:hover {
    background: var(--egun-bg);
    text-decoration: none;
}

.dashboard-message:focus-visible,
.dashboard-tile:focus-visible {
    outline: 2px solid var(--egun-blue);
    outline-offset: -2px;
}

.dashboard-message__chip {
    flex: none;
    min-width: 1.7em;
    padding: 0.18em 0.45em;
    border-radius: 999px;
    text-align: center;
    font-size: 0.85rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    background: var(--egun-gold);
    color: #1a1a1a;
}

.dashboard-message__chip--complaint {
    background: var(--egun-red);
    color: #fff;
}

.dashboard-message__text {
    flex: 1;
    font-size: 0.95rem;
}

.dashboard-message__chevron {
    font-size: 1.3rem;
    line-height: 1;
    color: var(--egun-text-muted);
}

.dashboard-group {
    margin-bottom: 1.1rem;
}

.dashboard-eyebrow--dot {
    display: flex;
    align-items: center;
    gap: 0.45em;
}

.dashboard-eyebrow--dot::before {
    content: "";
    width: 9px;
    height: 9px;
    border-radius: 50%;
    flex: none;
}

.dashboard-eyebrow--e::before { background: var(--egun-red); }
.dashboard-eyebrow--g::before { background: var(--egun-gold); }
.dashboard-eyebrow--u::before { background: var(--egun-blue); }
.dashboard-eyebrow--n::before { background: var(--egun-green); }

.dashboard-tiles {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.5rem;
}

.dashboard-tile {
    display: block;
    padding: 0.65rem 0.75rem;
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    color: var(--egun-text);
    font-size: 0.92rem;
    text-decoration: none;
    /* Labels WRAP instead of ellipsizing - several locales' labels are
       longer than any tile column ("Ersatzkäufer-Angebote" clipped,
       user-reported); hyphens keep long single words in check. */
    overflow-wrap: break-word;
    hyphens: auto;
}

.dashboard-tile:hover {
    border-color: var(--egun-blue);
    color: var(--egun-blue);
    text-decoration: none;
}

@media (min-width: 560px) {
    .dashboard-tiles {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

/* =====================================================================
   Dark mode - follows the device preference. The palette rides almost
   entirely on the CSS variables every component already uses; the block
   below additionally re-tints the handful of hardcoded light pastel
   backgrounds (status pills, flashes, legal notices, rating choices).
   ===================================================================== */
@media (prefers-color-scheme: dark) {
    :root {
        --egun-blue: #8e97ff;        /* readable link/accent blue on dark */
        --egun-blue-dark: #6b76f0;
        --egun-red: #ff6f64;
        --egun-green: #37b45c;
        --egun-text: #e7e7ec;
        --egun-text-muted: #a2a2ad;
        --egun-border: #3a3c44;
        --egun-bg: #131417;
        --egun-surface: #1e2026;
        --feedback-positive: #57c76b;
        --feedback-negative: #ff6f64;
        --feedback-neutral: #a2a2ad;
    }

    /* Solid buttons keep white text - the lighter accent blues above
       still carry enough contrast as fills. */
    button,
    input[type="submit"],
    .button-link,
    .button {
        color: #0e0f12;
    }
    .button-link--secondary,
    .btn-quiet {
        color: var(--egun-text);
    }

    /* The dashboard complaint chip: dark mode lightens --egun-red to
       #ff6f64, on which white text loses contrast - use dark ink like
       the solid buttons above. */
    .dashboard-message__chip--complaint { color: #0e0f12; }

    /* Same problem for the search sort chips: dark mode lightens
       --egun-blue to #8e97ff, on which white text loses contrast. */
    .sort-chip--active,
    .sort-chip--active:hover { color: #0e0f12; }

    /* ... and for the sell form's selected choice pills. */
    .choice-pills label:has(input:checked) { color: #0e0f12; }

    /* Red badges: dark mode lightens --egun-red - dark ink, same as the
       complaint chip. */
    .tab-bar__badge,
    .dashboard-tile__badge { color: #0e0f12; }

    /* Watchlist remove button: the light hover wash is invisible on dark. */
    .watchlist-list__remove:hover,
    .watchlist-list__remove:focus-visible { background: rgba(255, 255, 255, 0.1); }

    /* Green/amber/red tinted chips and boxes: dark equivalents. */
    .status-pill { background: #2a2c33; color: var(--egun-text-muted); }
    .status-pill--ok { background: #17301d; color: #57c76b; }
    .status-pill--bad { background: #38201d; color: #ff8a80; }
    .status-pill--pending { background: #33290f; color: #e5b84a; }

    .flash--success { background: #17301d; color: #57c76b; border-color: #235c31; }
    .flash--error, .error { background: #38201d; color: #ff8a80; border-color: #5c2b26; }
    .flash--notice { background: #1a2238; color: #9fb4ef; border-color: #2e3d6b; }

    .my-bid-row__status--winning { background: #17301d; color: #57c76b; }
    .my-bid-row__status--outbid { background: #38201d; color: #ff8a80; }
    .bid-standing--winning { background: #17301d; color: #57c76b; }
    .bid-standing--outbid { background: #38201d; color: #ff8a80; }

    .auction-legal-disclosures { background: #2e2810; }

    .rating-list__choice--positive:has(input:checked) { background: #17301d; }
    .rating-list__choice--neutral:has(input:checked) { background: #2a2c33; }
    .rating-list__choice--negative:has(input:checked) { background: #38201d; }

    .seller-positive-pct,
    a.seller-positive-pct,
    a.seller-positive-pct:hover { background: #17301d; color: #57c76b; }

    /* myGun pill: bright brand gold works on the dark surface. */
    .mygun-mark__g { color: var(--egun-gold); }
    .totp-state--on { background: #17301d; color: #57c76b; }
    .totp-state--off { background: #38201d; color: #ff8a80; }
    .push-settings__options-note { color: #57c76b; }

    /* Legacy seller descriptions assume a light page - keep their block
       readable by giving it a light island instead of inverting unknown
       inline-styled content. */
    .auction-description {
        background: #f5f5f7;
        color: #1a1a1a;
        border-radius: var(--radius);
        padding: 0.8rem;
    }

    /* The wordmark/ad images sit on white in light mode; keep the header
       legible by lifting the surface slightly instead of pure dark. */
    .site-header__ad img,
    .ad-strip img { background: #fff; border-radius: 4px; }
}

/* =============================================================
   Cropper.js v1.6.2 stylesheet (dist/cropper.min.css, verbatim)
   https://fengyuanchen.github.io/cropperjs - MIT License,
   Copyright 2015-present Chen Fengyuan. Required by the
   client-side image editor (assets/image-editor.js).
   ============================================================= */
/*!
 * Cropper.js v1.6.2
 * https://fengyuanchen.github.io/cropperjs
 *
 * Copyright 2015-present Chen Fengyuan
 * Released under the MIT license
 *
 * Date: 2024-04-21T07:43:02.731Z
 */.cropper-container{-webkit-touch-callout:none;direction:ltr;font-size:0;line-height:0;position:relative;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.cropper-container img{backface-visibility:hidden;display:block;height:100%;image-orientation:0deg;max-height:none!important;max-width:none!important;min-height:0!important;min-width:0!important;width:100%}.cropper-canvas,.cropper-crop-box,.cropper-drag-box,.cropper-modal,.cropper-wrap-box{bottom:0;left:0;position:absolute;right:0;top:0}.cropper-canvas,.cropper-wrap-box{overflow:hidden}.cropper-drag-box{background-color:#fff;opacity:0}.cropper-modal{background-color:#000;opacity:.5}.cropper-view-box{display:block;height:100%;outline:1px solid #39f;outline-color:rgba(51,153,255,.75);overflow:hidden;width:100%}.cropper-dashed{border:0 dashed #eee;display:block;opacity:.5;position:absolute}.cropper-dashed.dashed-h{border-bottom-width:1px;border-top-width:1px;height:33.33333%;left:0;top:33.33333%;width:100%}.cropper-dashed.dashed-v{border-left-width:1px;border-right-width:1px;height:100%;left:33.33333%;top:0;width:33.33333%}.cropper-center{display:block;height:0;left:50%;opacity:.75;position:absolute;top:50%;width:0}.cropper-center:after,.cropper-center:before{background-color:#eee;content:" ";display:block;position:absolute}.cropper-center:before{height:1px;left:-3px;top:0;width:7px}.cropper-center:after{height:7px;left:0;top:-3px;width:1px}.cropper-face,.cropper-line,.cropper-point{display:block;height:100%;opacity:.1;position:absolute;width:100%}.cropper-face{background-color:#fff;left:0;top:0}.cropper-line{background-color:#39f}.cropper-line.line-e{cursor:ew-resize;right:-3px;top:0;width:5px}.cropper-line.line-n{cursor:ns-resize;height:5px;left:0;top:-3px}.cropper-line.line-w{cursor:ew-resize;left:-3px;top:0;width:5px}.cropper-line.line-s{bottom:-3px;cursor:ns-resize;height:5px;left:0}.cropper-point{background-color:#39f;height:5px;opacity:.75;width:5px}.cropper-point.point-e{cursor:ew-resize;margin-top:-3px;right:-3px;top:50%}.cropper-point.point-n{cursor:ns-resize;left:50%;margin-left:-3px;top:-3px}.cropper-point.point-w{cursor:ew-resize;left:-3px;margin-top:-3px;top:50%}.cropper-point.point-s{bottom:-3px;cursor:s-resize;left:50%;margin-left:-3px}.cropper-point.point-ne{cursor:nesw-resize;right:-3px;top:-3px}.cropper-point.point-nw{cursor:nwse-resize;left:-3px;top:-3px}.cropper-point.point-sw{bottom:-3px;cursor:nesw-resize;left:-3px}.cropper-point.point-se{bottom:-3px;cursor:nwse-resize;height:20px;opacity:1;right:-3px;width:20px}@media (min-width:768px){.cropper-point.point-se{height:15px;width:15px}}@media (min-width:992px){.cropper-point.point-se{height:10px;width:10px}}@media (min-width:1200px){.cropper-point.point-se{height:5px;opacity:.75;width:5px}}.cropper-point.point-se:before{background-color:#39f;bottom:-50%;content:" ";display:block;height:200%;opacity:0;position:absolute;right:-50%;width:200%}.cropper-invisible{opacity:0}.cropper-bg{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC")}.cropper-hide{display:block;height:0;position:absolute;width:0}.cropper-hidden{display:none!important}.cropper-move{cursor:move}.cropper-crop{cursor:crosshair}.cropper-disabled .cropper-drag-box,.cropper-disabled .cropper-face,.cropper-disabled .cropper-line,.cropper-disabled .cropper-point{cursor:not-allowed}

/* =============================================================
   Client-side image editor modal (assets/image-editor.js).
   Deliberately a FIXED dark "photo editor" look in both themes -
   no dark-mode overrides needed, and the picture is always judged
   against a neutral dark surround.
   ============================================================= */
.image-editor {
    position: fixed;
    inset: 0;
    z-index: 1200;
    background: rgba(0, 0, 0, 0.55);
    display: flex;
}

.image-editor-open,
.image-editor-open body {
    overflow: hidden;
}

.image-editor__panel {
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
    background: #1c1c1e;
    color: #f2f2f2;
}

@media (min-width: 700px) {
    .image-editor {
        padding: 2rem;
    }

    .image-editor__panel {
        max-width: 56rem;
        margin: auto;
        height: min(90vh, 50rem);
        border-radius: 10px;
        overflow: hidden;
    }
}

.image-editor__header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.6rem 0.8rem 0.4rem;
}

.image-editor__header h2 {
    margin: 0;
    font-size: 1rem;
    color: #f2f2f2;
}

.image-editor__close {
    background: none;
    border: none;
    color: #f2f2f2;
    font-size: 1.5rem;
    line-height: 1;
    padding: 0 0.3rem;
}

.image-editor__tabs {
    display: flex;
    gap: 0.35rem;
    padding: 0 0.8rem 0.5rem;
    overflow-x: auto;
}

.image-editor__tab {
    background: #2c2c2e;
    color: #ddd;
    border: 1px solid #3a3a3c;
    border-radius: 999px;
    padding: 0.3rem 0.8rem;
    font-size: 0.85rem;
    white-space: nowrap;
    flex: 0 0 auto;
}

.image-editor__tab--active {
    background: var(--egun-gold);
    border-color: var(--egun-gold);
    color: #1c1c1e;
    font-weight: 700;
}

.image-editor__stage {
    flex: 1;
    min-height: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0.4rem 0.8rem;
    /* Checker-free neutral surface behind transparent PNGs. */
    background: #101012;
}

.image-editor__crop-wrap {
    width: 100%;
    height: 100%;
}

.image-editor__crop-wrap img {
    display: block;
    max-width: 100%;
}

.image-editor__preview {
    max-width: 100%;
    max-height: 100%;
    /* The canvas handles its own pointer gestures (text drag /
       drawing) - the page must not scroll underneath a finger. */
    touch-action: none;
}

.image-editor__controls {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    padding: 0.6rem 0.8rem;
}

.image-editor__controls label {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.8rem;
    color: #ccc;
    margin: 0;
}

.image-editor__controls input[type="text"] {
    flex: 1 1 10rem;
    min-width: 0;
    background: #2c2c2e;
    border: 1px solid #3a3a3c;
    border-radius: 6px;
    color: #fff;
    padding: 0.4rem 0.5rem;
    font-size: 16px; /* prevents the iOS focus auto-zoom */
}

.image-editor__controls input[type="range"] {
    width: 7rem;
    accent-color: var(--egun-gold);
}

.image-editor__btn {
    background: #2c2c2e;
    color: #eee;
    border: 1px solid #3a3a3c;
    border-radius: 6px;
    padding: 0.4rem 0.7rem;
    font-size: 0.85rem;
}

.image-editor__btn:disabled {
    opacity: 0.35;
}

.image-editor__btn--push {
    margin-left: auto;
}

.image-editor__primary {
    background: var(--egun-gold);
    color: #1c1c1e;
    border: none;
    border-radius: 6px;
    padding: 0.4rem 1.1rem;
    font-size: 0.9rem;
    font-weight: 700;
}

.image-editor__swatches {
    display: flex;
    gap: 0.35rem;
    align-items: center;
}

.image-editor__swatch {
    width: 1.5rem;
    height: 1.5rem;
    border-radius: 50%;
    border: 2px solid #3a3a3c;
    padding: 0;
    flex: 0 0 auto;
}

.image-editor__swatch--active {
    border-color: #fff;
    box-shadow: 0 0 0 2px var(--egun-gold);
}

.image-editor__hint {
    flex-basis: 100%;
    margin: 0;
    font-size: 0.75rem;
    color: #9a9a9a;
}

.image-editor__footer {
    display: flex;
    gap: 0.5rem;
    padding: 0.6rem 0.8rem;
    padding-bottom: calc(0.6rem + env(safe-area-inset-bottom));
    border-top: 1px solid #3a3a3c;
}

/* "Bearbeiten" pencil in the sell-form thumbnail top bar. */
.sell-image-thumbnails__bar-actions {
    display: flex;
    gap: 0.3rem;
    align-items: center;
}

.sell-image-thumbnails__edit {
    width: 1.5rem;
    height: 1.5rem;
    padding: 0;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.55);
    color: #fff;
    font-size: 0.85rem;
    line-height: 1;
    border: none;
    flex: 0 0 auto;
}

/* Single-image preview + edit button (my-listings edit page). */
.image-edit-preview {
    display: flex;
    align-items: flex-end;
    gap: 0.6rem;
    margin-top: 0.5rem;
}

.image-edit-preview__img {
    height: 100px;
    border-radius: var(--radius);
    object-fit: cover;
}

.image-edit-preview__button {
    flex: 0 0 auto;
}

/* Social proof, redesigned 2026-07-21: urgency lives IN the Restzeit row
   (red ticking digits + inline "endet bald" chip, same 1h threshold and
   same red as the Auktionspuls's critical state - one urgency system,
   two coordinated expressions), and the watcher count sits with the
   Gebote line as quiet demand meta. */
.auction-restzeit--soon strong {
    color: var(--egun-red);
}

.restzeit-soon-chip {
    display: inline-block;
    margin-left: 0.5rem;
    padding: 0.1rem 0.55rem;
    border-radius: 999px;
    background: var(--egun-red);
    color: #fff;
    font-size: 0.72rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    vertical-align: 0.12em;
    text-transform: none;
}


/* Follow-seller controls (2026-07-21) - on the item seller card and the
   storefront header. */
.seller-follow-form {
    margin: 0 0 0.5rem;
}

.seller-followers {
    margin: 0 0 0.35rem;
    color: var(--egun-text-muted);
}

/* Storefront identity band: on the phone a plain wrapper (h1 and the
   follow row stack exactly as they always did); the desktop layer turns
   it into one baseline row - see desktop.css. */
.storefront-head { margin: 0; }

/* Storefront toolbar variant with TWO chip groups (type + sort): on the
   phone each nav takes a full row so the groups never interleave
   mid-wrap - eight look-alike pills with no boundary read as soup. The
   desktop layer relaxes this back to one line. */
.search-toolbar--grouped .search-toolbar__sort { flex-basis: 100%; }

.storefront-follow {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.9rem;
    margin: 0 0 1rem;
}

.storefront-follow__count {
    color: var(--egun-text-muted);
    font-size: 0.9rem;
}

.storefront-follow .seller-follow-form {
    margin: 0;
}

/* "Gefolgte Verkäufer" management page (2026-07-21). */
.followed-sellers {
    list-style: none;
    margin: 0 0 1rem;
    padding: 0;
}

.followed-sellers__row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    padding: 0.65rem 0;
    border-bottom: 1px solid var(--egun-border, #e3e3e3);
}

.followed-sellers__who {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0;
}

.followed-sellers__count {
    color: var(--egun-text-muted);
}

.followed-sellers__row form {
    margin: 0;
    flex-shrink: 0;
}

.followed-sellers__hint {
    color: var(--egun-text-muted);
}

/* Parcel tracking (2026-07-21): the Versendet dialog + shipment info
   lines on my-sales (seller) and my-purchases (buyer). */
.ship-dialog {
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 1.1rem;
    max-width: 24rem;
    width: calc(100vw - 2.5rem);
}

.ship-dialog::backdrop {
    background: rgba(0, 0, 0, 0.45);
}

.ship-dialog h2 {
    margin: 0 0 0.8rem;
    font-size: 1.05rem;
}

.ship-dialog label {
    display: block;
    margin: 0.6rem 0 0.2rem;
    font-size: 0.85rem;
    color: var(--egun-text-muted);
}

.ship-dialog select,
.ship-dialog input {
    width: 100%;
}

.ship-dialog__hint {
    margin: 0.8rem 0 0;
    font-size: 0.8rem;
    color: var(--egun-text-muted);
}

.ship-dialog__actions {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-top: 0.9rem;
}

.my-sales-shipment {
    margin: 0.2rem 0 0.4rem;
    font-size: 0.85rem;
    color: var(--egun-text-muted);
}

.my-sales-shipment__nr {
    font-family: inherit;
    word-break: break-all;
}

.purchase-shipments {
    list-style: none;
    margin: 0 0 0.5rem;
    padding: 0;
    font-size: 0.85rem;
    color: var(--egun-text-muted);
}

.purchase-shipments li {
    padding: 0.1rem 0;
    word-break: break-word;
}

/* CSV bulk upload (2026-07-21). */
.sell-bulk-form {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    margin: 1rem 0;
    max-width: 30rem;
}

.sell-bulk-form label {
    margin-top: 0.5rem;
    font-weight: 600;
}

.sell-bulk-hint {
    color: var(--egun-text-muted);
}

.sell-bulk-summary__ok {
    color: #1a8a3d;
    font-weight: 600;
}

.sell-bulk-summary__bad {
    color: var(--egun-red);
    font-weight: 600;
}

.sell-bulk-errors {
    margin: 0.6rem 0;
}

.sell-bulk-errors ul {
    margin: 0.4rem 0 0;
    padding-left: 1.2rem;
    font-size: 0.85rem;
}

.sell-bulk-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.85rem;
    margin: 0.8rem 0;
}

.sell-bulk-table th,
.sell-bulk-table td {
    padding: 0.35rem 0.5rem;
    border-bottom: 1px solid var(--egun-border);
    text-align: left;
}

.sell-bulk-confirm {
    display: block;
    margin: 0.8rem 0;
    font-weight: 600;
}

.sell-bulk-cancel {
    margin-top: 1.2rem;
}

/* Bulk-upload audit 2026-08-05: publish warnings, resume banner, format help */
.sell-bulk-warning {
    margin-top: 0.3rem;
    font-size: 0.8rem;
    color: var(--egun-red, #c0392b);
}

.sell-bulk-open-batch {
    margin-bottom: 1rem;
}
.sell-bulk-open-batch p {
    margin: 0.2rem 0;
}

.sell-bulk-format {
    margin: 1rem 0;
    font-size: 0.9rem;
}
.sell-bulk-format summary {
    cursor: pointer;
    font-weight: 600;
}
.sell-bulk-format ul {
    margin: 0.5rem 0 0 1.2rem;
    color: var(--egun-text-muted, #666);
}
.sell-bulk-format li {
    margin-bottom: 0.3rem;
}

#bulk-progress {
    display: block;
    width: 100%;
    margin-top: 0.6rem;
}

/* The Kerbe: cards carry a 3px left edge in the color of their world
   letter (sampled from the eGun wordmark - e=red Verkaufen, G=gold
   Kaufen, u=blue Community, n=green Konto), extending the dashboard's
   dot coding to the app's surfaces. The trade card is exempt - its
   signature is the Auktionspuls top edge, one device per card.
   MUST stay at the END of this file: the cards' own later `border:`
   shorthands would otherwise reset the left edge (source order). */
.list-item,
.auction-description,
.auction-seller,
.auction-shipping {
    border-left: 3px solid var(--egun-gold);
}

.cafe-post,
.rating-summary {
    border-left: 3px solid var(--egun-blue);
}

.sell-preview,
.my-sales-row {
    border-left: 3px solid var(--egun-red);
}

/* --- In-app messages (Option B, 2026-07-18) --- */

.message-threads {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.message-thread {
    display: block;
    padding: 0.65rem 0.8rem;
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-left: 3px solid var(--egun-blue);
    border-radius: var(--radius);
    color: var(--egun-text);
    text-decoration: none;
}

.message-thread:hover {
    text-decoration: none;
    border-color: var(--egun-blue);
}

.message-thread__top {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.message-thread__when {
    margin-left: auto;
    font-size: 0.8rem;
    color: var(--egun-text-muted);
    white-space: nowrap;
}

.message-thread__unread {
    min-width: 1.2rem;
    padding: 0.05em 0.35em;
    border-radius: 999px;
    background: var(--egun-red);
    color: #fff;
    font-size: 0.72rem;
    font-weight: 700;
    text-align: center;
}

.message-thread__subject,
.message-thread__preview {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 0.85rem;
    color: var(--egun-text-muted);
}

.message-thread__subject {
    font-weight: 600;
}

.message-thread--unread .message-thread__preview {
    color: var(--egun-text);
    font-weight: 600;
}

/* --- Inbox overhaul (2026-08-10): identity, auction context, state --- */

.message-head {
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
}

.message-head__chip {
    padding: 0.1em 0.55em;
    border-radius: 999px;
    background: var(--egun-red);
    color: #fff;
    font-size: 0.78rem;
    font-weight: 700;
    white-space: nowrap;
}

.message-tools {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    margin: 0 0 0.9rem;
}

.message-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
}

.message-filters__pill {
    padding: 0.2rem 0.7rem;
    border: 1px solid var(--egun-border);
    border-radius: 999px;
    background: var(--egun-surface);
    color: var(--egun-text);
    font-size: 0.82rem;
    text-decoration: none;
    white-space: nowrap;
}

.message-filters__pill:hover {
    border-color: var(--egun-blue);
    text-decoration: none;
}

.message-filters__pill--active {
    background: var(--egun-blue);
    border-color: var(--egun-blue);
    color: #fff;
    font-weight: 600;
}

.message-search {
    flex: 1 1 11rem;
    min-width: 9rem;
    padding: 0.3rem 0.6rem;
    border: 1px solid var(--egun-border);
    border-radius: 999px;
    font-size: 0.85rem;
}

.message-thread__score {
    font-size: 0.8rem;
    color: var(--egun-text-muted);
}

.message-thread__business,
.message-partner__business {
    padding: 0.05em 0.45em;
    border: 1px solid var(--egun-border);
    border-radius: 999px;
    font-size: 0.68rem;
    color: var(--egun-text-muted);
    white-space: nowrap;
}

.message-thread__auction {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    min-width: 0;
    margin-top: 0.25rem;
    font-size: 0.85rem;
}

.message-thread__thumb {
    width: 28px;
    height: 28px;
    object-fit: cover;
    border-radius: 4px;
    flex: 0 0 auto;
}

.message-thread__auction-title {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
    font-weight: 600;
    color: var(--egun-text);
}

.message-thread__auction-price {
    white-space: nowrap;
    color: var(--egun-text);
}

.message-state {
    padding: 0.05em 0.5em;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 700;
    white-space: nowrap;
}

.message-state--live {
    background: rgba(0, 128, 0, 0.12);
    color: var(--egun-green, #0a0);
}

.message-state--soon {
    background: rgba(200, 140, 0, 0.15);
    color: #a66a00;
}

.message-state--ended {
    background: var(--egun-bg);
    color: var(--egun-text-muted);
    border: 1px solid var(--egun-border);
}

.message-state--sold {
    background: rgba(37, 25, 188, 0.1);
    color: var(--egun-blue);
}

.message-thread__you {
    font-weight: 600;
    color: var(--egun-text);
}

.message-ticks {
    color: var(--egun-text-muted);
    letter-spacing: -0.15em;
    padding-right: 0.15em;
}

.message-ticks--read {
    color: var(--egun-blue);
}

.message-thread__awaiting {
    display: inline-block;
    margin-top: 0.25rem;
    font-size: 0.7rem;
    font-weight: 700;
    color: #a66a00;
}

.message-partner {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0 0 0.5rem;
}

.message-partner__nick {
    margin: 0;
}

.message-partner__feedback {
    font-size: 0.82rem;
}

.message-listing {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.5rem 0.65rem;
    margin-bottom: 0.9rem;
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    color: var(--egun-text);
    text-decoration: none;
}

.message-listing:hover {
    border-color: var(--egun-blue);
    text-decoration: none;
}

.message-listing__thumb {
    width: 48px;
    height: 48px;
    object-fit: cover;
    border-radius: 4px;
    flex: 0 0 auto;
}

.message-listing__text {
    min-width: 0;
}

.message-listing__title {
    display: block;
    font-weight: 600;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.message-listing__meta {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.85rem;
}

.message-day {
    align-self: center;
    padding: 0.1em 0.7em;
    border-radius: 999px;
    background: var(--egun-bg);
    border: 1px solid var(--egun-border);
    color: var(--egun-text-muted);
    font-size: 0.72rem;
}

.message-bubble__mail {
    white-space: nowrap;
}

.message-list {
    list-style: none;
    margin: 0 0 1rem;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.message-bubble {
    max-width: 85%;
    padding: 0.55rem 0.75rem;
    border-radius: var(--radius);
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
}

.message-bubble--mine {
    align-self: flex-end;
    border-left: 3px solid var(--egun-green);
}

.message-bubble--theirs {
    align-self: flex-start;
    border-left: 3px solid var(--egun-blue);
}

.message-bubble__body {
    margin: 0;
    overflow-wrap: anywhere;
}

.message-bubble__meta {
    margin: 0.3rem 0 0;
    font-size: 0.75rem;
    color: var(--egun-text-muted);
}

.message-reply textarea {
    width: 100%;
}

/* --- Message attachments (2026-08-14) --- Images render as the picture
   itself (tap = full size in a new tab), PDFs as a file chip; a purged
   file (12-month retention) keeps its name as a muted tombstone. */
.message-attachment {
    display: block;
    margin: 0.4rem 0 0;
}

.message-attachment--image img {
    display: block;
    max-width: min(100%, 260px);
    max-height: 260px;
    border-radius: calc(var(--radius) - 2px);
    border: 1px solid var(--egun-border);
}

.message-attachment--file {
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
    padding: 0.45rem 0.6rem;
    border: 1px solid var(--egun-border);
    border-radius: calc(var(--radius) - 2px);
    background: var(--egun-bg);
    text-decoration: none;
    max-width: 100%;
}

.message-attachment__name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    overflow-wrap: anywhere;
}

.message-attachment__size {
    flex-shrink: 0;
    font-size: 0.75rem;
    color: var(--egun-text-muted);
}

.message-attachment--purged {
    font-size: 0.8rem;
    font-style: italic;
    color: var(--egun-text-muted);
}

.message-attach {
    margin: 0.5rem 0;
}

.message-attach__label {
    display: block;
    font-size: 0.85rem;
    margin-bottom: 0.2rem;
}

.message-attach__hint {
    margin: 0.2rem 0 0;
    color: var(--egun-text-muted);
}


/* --- Home swipe rails (Specials / Top-Auktionen, 2026-07-18) ---
   Manual horizontal swiping, deliberately NO auto-rotation (user
   decision): a peeking next card is the affordance, scroll-snap gives
   clean stops, and nothing ever moves under the user's finger. Bleeds
   to the screen edges so the cut-off card reads as "there's more". */
.auction-rail {
    flex-direction: row;
    overflow-x: auto;
    margin-left: -1rem;
    margin-right: -1rem;
    padding: 0 1rem 0.3rem;
    scroll-snap-type: x mandatory;
    scroll-padding-left: 1rem;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}

.auction-rail::-webkit-scrollbar {
    display: none;
}

/* Desktop (mouse): the hidden scrollbar left no way to scroll the rails
   at all (user-reported) - show a slim, draggable one there. Touch
   devices keep the clean edge-to-edge look and swipe instead. */
@media (hover: hover) and (pointer: fine) {
    .auction-rail {
        scrollbar-width: thin;
        scrollbar-color: var(--egun-border) transparent;
        padding-bottom: 0.6rem;
    }

    .auction-rail::-webkit-scrollbar {
        display: block;
        height: 8px;
    }

    .auction-rail::-webkit-scrollbar-thumb {
        background: var(--egun-border);
        border-radius: 999px;
    }

    .auction-rail::-webkit-scrollbar-track {
        background: transparent;
    }
}

.auction-rail > li {
    flex: 0 0 min(84%, 330px);
    display: flex;
    scroll-snap-align: start;
}

.auction-rail > li > .list-item {
    flex: 1 1 auto;
}

/* Rail cards are image-forward showcase tiles (these are PAID
   placements): full-width photo on top, then title / price / meta
   stacked - the side-thumbnail layout wasted the card on whitespace
   and squeezed the meta onto two lines (user-reported). The Kerbe
   left edge stays untouched. */
.auction-rail .list-item {
    padding: 0 0 0.55rem;
    align-items: stretch;
}

.auction-rail .list-item__link {
    flex-direction: column;
    align-items: stretch;
    gap: 0.45rem;
}

.auction-rail .list-item__thumb {
    width: 100%;
    height: 150px;
    border-radius: 5px 5px 0 0;
}

.auction-rail .list-item__body {
    padding: 0 0.7rem;
}

.auction-rail .list-item__title {
    /* star sits on the photo now, not beside the title */
    padding-right: 0;
    /* Uniform card anatomy (user request 2026-08-09): the title block
       takes all spare height, its text at the top and the pill line
       pinned to its bottom - so pills, price and the count/time line
       sit at the SAME position in every card of a rail no matter how
       long the title is or whether the price line wraps. */
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    gap: 0.3rem;
}

.auction-rail .list-item__title-text {
    display: block;
}

.auction-rail .list-item__title .list-item__tags {
    margin-top: auto;
}

/* The watch star moves onto the photo - white chip for contrast. */
.auction-rail .list-item__watch-form,
.auction-rail .list-item__watch--disabled {
    top: 0.45rem;
    right: 0.55rem;
}

.auction-rail .list-item__watch {
    display: grid;
    place-items: center;
    /* 2.8rem box - 0.45rem padding ring = the same 1.9rem visible circle
       as before, now with a ~45px touch target; background-clip keeps the
       white chip on the content box only (the H5 hit-area padding had
       shifted the glyph off-center - user report 2026-07-19). */
    width: 2.8rem;
    height: 2.8rem;
    padding: 0.45rem;
    margin: -0.45rem;
    background-clip: content-box;
    border-radius: 50%;
    background-color: rgba(255, 255, 255, 0.88);
    color: #666;
}

.auction-rail .list-item__watch--active {
    color: var(--egun-gold);
}

.auction-rail > li.empty-state {
    flex: 0 0 100%;
    display: block;
}

/* --- Wanted-ads category tiles (2026-07-18 redesign) --- */

.wanted-intro {
    color: var(--egun-text-muted);
    margin-top: -0.3rem;
}

.wanted-cats {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.5rem;
    margin-top: 1rem;
}

.wanted-cat {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.65rem 0.75rem;
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-left: 3px solid var(--egun-gold);
    border-radius: var(--radius);
    color: var(--egun-text);
    font-size: 0.92rem;
    font-weight: 500;
    text-decoration: none;
    overflow-wrap: anywhere;
}

.wanted-cat:hover {
    border-color: var(--egun-blue);
    color: var(--egun-blue);
    text-decoration: none;
}

.count-chip--zero {
    background: var(--egun-border);
    color: var(--egun-text-muted);
    font-weight: 600;
}

/* --- Wanted-ad cards (subpages, 2026-07-18 redesign) --- */

.wanted-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.wanted-ad {
    padding: 0.65rem 0.8rem;
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-left: 3px solid var(--egun-gold);
    border-radius: var(--radius);
}

.wanted-ad__text {
    margin: 0 0 0.35rem;
    font-size: 0.9rem;
    font-weight: 500;
    overflow-wrap: anywhere;
}

.wanted-ad__meta {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 0.1rem 0.5rem;
    margin: 0;
    font-size: 0.8rem;
    color: var(--egun-text-muted);
}

.wanted-ad__price {
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 1.05rem;
    color: var(--egun-text);
    font-variant-numeric: tabular-nums;
}

.wanted-ad__ends {
    margin-left: auto;
    white-space: nowrap;
}

.wanted-ad__actions {
    margin: 0.5rem 0 0;
}

/* Saved Notiz shown inside purchase/sale cards - a quiet gold-edged
   annotation, visually the OWNER's own margin note. */
.row-note {
    margin: 0.6rem 0 0;
    padding: 0.45rem 0.65rem;
    background: var(--egun-bg);
    border-left: 3px solid var(--egun-gold);
    border-radius: 0 var(--radius) var(--radius) 0;
    font-size: 0.85rem;
    overflow-wrap: anywhere;
}

/* --- /my-haggles card redesign (2026-07-18) --- */

.my-haggle-row__offer {
    margin: 0.6rem 0 0.2rem;
}

.my-haggle-row__offer .section-eyebrow {
    margin: 0 0 0.1rem;
}

.my-haggle-row__amount {
    margin: 0;
    font-family: var(--font-display);
    font-size: 1.5rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.my-haggle-row__counter-info {
    margin: 0.1rem 0 0;
    font-size: 0.85rem;
    color: var(--egun-text-muted);
}

.my-haggle-row__actions {
    display: flex;
    flex-direction: column;
    gap: 0.55rem;
    margin-top: 0.6rem;
}

.my-haggle-row__accept {
    margin: 0;
}

.my-haggle-row__accept button {
    width: 100%;
}

/* Counter offer: input + Senden fused into one row (search-bar grammar) */
.my-haggle-row__counter {
    display: flex;
    gap: 0.4rem;
    margin: 0;
}

.my-haggle-row__counter input {
    flex: 1 1 auto;
    min-width: 0;
}

.my-haggle-row__counter button {
    flex: 0 0 auto;
}

.my-haggle-row__reject-form {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.4rem 0.7rem;
    margin: 0;
}

.my-haggle-row__blacklist {
    font-size: 0.82rem;
    color: var(--egun-text-muted);
}


/* Card-level anchors (whole cards wrapped in one <a>): the global
   a:hover underline decorated EVERY line of these cards at once - it
   read as a rendering glitch (2026-07-18 design audit, finding #1).
   Hover feedback on cards is border/color, never underline. */
a.dashboard-message:hover,
a.my-purchase-row__head:hover,
a.revoke-request-row__link:hover,
a.runner-up-offer-row__link:hover,
a.saved-search-row__link:hover,
a.rating-list__item-link:hover,
a.message-thread:hover,
a.list-item__link:hover {
    text-decoration: none;
}


/* Profile sections: same eyebrow grammar as the rest of the app, with
   the Konto world's green dot (audit #5). */
/* Exactly the fieldset-legend eyebrow (user request 2026-07-19: no world
   dot, same size/style as "Adressdaten"). */
.profile-section > h2 {
    margin: 0 0 0.5rem;
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.09em;
    color: var(--egun-text-muted);
}

/* --- Forum redesign (2026-07-18, wanted-ads grammar / Community blue) --- */

.cafe-cats {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-top: 0.8rem;
}

.cafe-cat {
    display: block;
    padding: 0.65rem 0.75rem;
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-left: 3px solid var(--egun-blue);
    border-radius: var(--radius);
    color: var(--egun-text);
    text-decoration: none;
}

.cafe-cat:hover {
    border-color: var(--egun-blue);
    text-decoration: none;
}

.cafe-cat__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

.cafe-cat__name {
    font-weight: 600;
    font-size: 0.95rem;
}

.cafe-cat__descr {
    display: block;
    margin-top: 0.15rem;
    font-size: 0.82rem;
    color: var(--egun-text-muted);
}

.cafe-posts {
    list-style: none;
    margin: 0 0 1rem;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.cafe-post {
    background: var(--egun-surface);
    border-left-color: var(--egun-blue);
}

.cafe-post__meta {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.3rem 0.5rem;
}

.cafe-post__date {
    margin-left: auto;
    white-space: nowrap;
    font-size: 0.8rem;
}

.cafe-post__text {
    overflow-wrap: anywhere;
}

.cafe-new-post {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-top: 1.2rem;
}

.cafe-new-post textarea {
    width: 100%;
}

.cafe-post__auctions {
    font-size: 0.8rem;
    white-space: nowrap;
}

/* Forums-Richtlinien (cafe audit B3) - quiet disclosure under the compose form */
.cafe-rules {
    margin-top: 0.75rem;
    font-size: 0.85rem;
    color: var(--egun-text-muted);
}

.cafe-rules summary {
    cursor: pointer;
}

.cafe-rules__list {
    margin: 0.5rem 0 0;
    padding-left: 1.25rem;
}

.cafe-rules__list li {
    margin-bottom: 0.5rem;
}

/* Watchlist per-item note (watchlist audit 2026-08-06) */
.watchlist-note {
    margin: 0.3rem 0 0.6rem;
    font-size: 0.85rem;
}

.watchlist-note summary {
    cursor: pointer;
    color: var(--egun-text-muted);
}

.watchlist-note__text {
    color: var(--egun-text);
    font-style: italic;
}

.watchlist-note__form {
    display: flex;
    gap: 0.4rem;
    margin-top: 0.4rem;
}

.watchlist-note__form input[type="text"] {
    flex: 1 1 auto;
    min-width: 0;
}

/* Public withdrawal entry (revoke-purchase, 2026-08-06) */
.revoke-deal-details {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: 0.3rem 1rem;
    margin: 0 0 1rem;
}

.revoke-deal-details dt {
    font-weight: bold;
}

.revoke-deal-details dd {
    margin: 0;
}

/* --- Bid/buy confirmation sheet + success toasts (2026-07-19) --- */

/* Bottom sheet on phones, centered card from 520px up. border-left after
   the border shorthand INSIDE the same rule = safe Kerbe (gold: a
   Kaufen-world moment). */
.confirm-sheet {
    border: 1px solid var(--egun-border);
    border-left: 3px solid var(--egun-gold);
    border-radius: var(--radius) var(--radius) 0 0;
    background: var(--egun-surface);
    color: var(--egun-text);
    padding: 1.1rem 1rem calc(1.1rem + env(safe-area-inset-bottom, 0px));
    width: 100%;
    max-width: none;
    margin: auto 0 0;
}

.confirm-sheet::backdrop {
    background: rgba(0, 0, 0, 0.45);
}

@media (min-width: 520px) {
    .confirm-sheet {
        width: auto;
        min-width: 20rem;
        max-width: 26rem;
        margin: auto;
        border-radius: var(--radius);
        padding-bottom: 1.1rem;
    }
}

.confirm-sheet h3 {
    margin: 0 0 0.35rem;
}

.confirm-sheet__amount {
    margin: 0;
    font-family: var(--font-display);
    font-weight: 600;
    font-size: 1.65rem;
    line-height: 1.15;
}

.confirm-sheet__detail {
    margin: 0.1rem 0 0;
    font-size: 0.9rem;
    color: var(--egun-text-muted);
}

.confirm-sheet__note {
    margin: 0.35rem 0 0.9rem;
    font-size: 0.85rem;
    color: var(--egun-text-muted);
}

.confirm-sheet__actions {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.confirm-sheet__ok {
    width: 100%;
}

.confirm-sheet__cancel {
    width: 100%;
    text-align: center;
}

@media (prefers-reduced-motion: no-preference) {
    .confirm-sheet[open] {
        animation: confirm-sheet-in 0.22s ease-out;
    }

    @keyframes confirm-sheet-in {
        from { transform: translateY(1.5rem); opacity: 0; }
        to { transform: translateY(0); opacity: 1; }
    }
}

/* Success toasts: fixed above the tab bar, 3s lifetime (removal by JS in
   app.js; the CSS animation only handles the fade). Errors are NOT
   toasts - they stay as persistent inline .flash--error. */
.toast-stack {
    position: fixed;
    left: 0.75rem;
    right: 0.75rem;
    bottom: calc(var(--tab-bar-h, 0rem) + 0.75rem + env(safe-area-inset-bottom, 0px));
    z-index: 60;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    pointer-events: none;
}

.toast {
    pointer-events: auto;
    margin: 0 auto;
    max-width: 26rem;
    background: var(--egun-surface);
    color: var(--egun-text);
    border: 1px solid var(--egun-border);
    border-left: 3px solid var(--egun-green);
    border-radius: var(--radius);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.18);
    padding: 0.7rem 0.9rem 0.7rem 0.8rem;
    font-weight: 500;
    cursor: pointer;
}

.toast::before {
    content: '✓';
    color: var(--egun-green);
    font-weight: 700;
    margin-right: 0.45rem;
}

@media (prefers-reduced-motion: no-preference) {
    .toast {
        animation: toast-life 3s ease forwards;
    }

    @keyframes toast-life {
        0% { transform: translateY(0.6rem); opacity: 0; }
        8% { transform: translateY(0); opacity: 1; }
        85% { opacity: 1; }
        100% { opacity: 0; }
    }
}

/* --- Bidding standing banner (2026-07-19): item-page "you're winning /
   you were outbid". Reuses the /my-bids status-pill palette (cohesion:
   same fact, same colors) as a full-width banner with a leading status
   dot, gated to the trade card's world. Filled by detail.html.twig's
   script from the private /my-bid-status endpoint. --- */
.bid-standing {
    margin: 0 0 0.7rem;
    padding: 0.5rem 0.7rem;
    border-radius: var(--radius);
    font-size: 0.92rem;
    font-weight: 600;
    /* Wrap as whole units: status on one line, amount on the next when they
       don't both fit - the amount itself never breaks mid-value. */
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    column-gap: 0.5rem;
    row-gap: 0.15rem;
}

.bid-standing__status {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    white-space: nowrap;
}

.bid-standing__status::before {
    content: '';
    flex: 0 0 auto;
    width: 0.6rem;
    height: 0.6rem;
    border-radius: 50%;
    background: currentColor;
}

.bid-standing__amount {
    white-space: nowrap;
    font-weight: 500;
}

.bid-standing--winning {
    background: #e6f4ea;
    color: #1a7a35;
}

.bid-standing--outbid {
    background: #fdecea;
    color: #b3261e;
}

/* Category intro line (SEO/UX, 2026-07-19): one descriptive sentence under
   the category h1. */
.category-intro {
    margin: 0.2rem 0 0.9rem;
    color: var(--egun-text-muted);
    font-size: 0.92rem;
}

/* Proxy-bidding hint under the bid input (UX audit C2). */
.bid-form__hint {
    margin: 0.15rem 0 0.4rem;
    color: var(--egun-text-muted);
    line-height: 1.3;
}

/* Outbid-push nudge (UX audit H1): one quiet row under the standing
   banner, offered exactly when the viewer became a bidder. */
.push-nudge {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0 0 0.7rem;
    padding: 0.5rem 0.6rem;
    background: var(--egun-bg);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    font-size: 0.88rem;
}

.push-nudge__text {
    flex: 1 1 auto;
}

.push-nudge__on {
    flex: 0 0 auto;
    border: 1px solid var(--egun-blue);
    border-radius: var(--radius-control, 4px);
    background: var(--egun-blue);
    color: #fff;
    padding: 0.35rem 0.7rem;
    font-weight: 600;
    cursor: pointer;
}

.push-nudge__dismiss {
    flex: 0 0 auto;
    background: none;
    border: none;
    color: var(--egun-text-muted);
    font-size: 0.95rem;
    padding: 0.45rem;
    margin: -0.45rem -0.2rem -0.45rem 0;
    cursor: pointer;
}

/* "Was bedeutet EWB/MES?" explainer triggers (UX audit N3). Styled as a
   DEFINITION affordance (muted text, dotted underline - "explanation
   available", not navigation); the :hover/:focus overrides are load-
   bearing: the global `button:hover` primary-blue fill would otherwise
   paint these unreadable (user report 2026-07-19). */
.disclosure-info-row {
    margin: 0.15rem 0 0.35rem;
}

.disclosure-info,
.disclosure-info:hover,
.disclosure-info:focus {
    background: none;
    color: var(--egun-text-muted);
}

.disclosure-info {
    border: none;
    padding: 0.3rem 0;
    font-size: 0.85rem;
    text-decoration: underline dotted;
    text-underline-offset: 3px;
    cursor: pointer;
}

.disclosure-info:hover {
    color: var(--egun-text);
}

.disclosure-info--chip {
    text-decoration: none;
    border: 1px solid var(--egun-border);
    border-radius: 50%;
    width: 1.7rem;
    height: 1.7rem;
    padding: 0;
    margin-left: 0.3rem;
    font-weight: 700;
    vertical-align: middle;
}

.disclosure-info--chip:hover {
    border-color: var(--egun-text-muted);
}

/* Collapsed-haggle additions (UX review 2026-07-19). */
.price-haggle-hint {
    margin: -0.4rem 0 0.3rem;
    color: var(--egun-text-muted);
}

/* The proposal form inside the sheet stacks full-width. */
.confirm-sheet .auction-haggle__form {
    display: block;
    margin: 0.6rem 0 0;
}

.confirm-sheet .auction-haggle__form input[type="text"] {
    width: 100%;
    margin: 0.25rem 0 0;
}

/* Dashboard deep-link landing (2026-08-10): the row the notice was about
   flashes gold once, and anchors land clear of the sticky header. */
.my-purchase-row,
.my-sales-buyer-row {
    scroll-margin-top: 5rem;
}

.row-focus-flash {
    animation: row-focus-flash 2.4s ease-out 1;
    border-radius: var(--radius);
}

@keyframes row-focus-flash {
    0%, 55% { box-shadow: 0 0 0 3px var(--egun-gold); }
    100% { box-shadow: 0 0 0 3px transparent; }
}

@media (prefers-reduced-motion: reduce) {
    .row-focus-flash { animation: none; box-shadow: 0 0 0 3px var(--egun-gold); }
}

/* Photo-less listings: the placeholder stage is a desktop-only device
   (the desktop layer reveals it); phones keep their old no-box layout. */
.auction-gallery--empty {
    display: none;
}

.auction-gallery__none {
    margin: 0;
    color: var(--egun-text-muted);
    font-size: 0.9rem;
}

/* Item-facts strip (constant-anatomy redesign 2026-08-09): the rows the
   trade card used to carry (Zustand, Hersteller, Kaliber, Versandkosten,
   Artikel-IDs) as one quiet ledger card - label:value pairs flowing into
   as many columns as the width allows (one on phones, two or three on
   the full-width desktop row, eBay-"Artikelmerkmale"-style). */
.item-details {
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.75rem 1rem;
    margin-bottom: 1rem;
}

/* Content-sized pairs flowing left to right (user 2026-08-09: a pair
   must stay on ONE line - fixed grid tracks either overlapped or wrapped
   the long "Artikel-Nr. des Verkäufers" pair). Each pair takes exactly
   the width it needs; the ROW wraps between pairs, never inside one.
   Only a pair wider than the whole strip (max dealer SKU on a narrow
   phone) breaks inside the value as a last resort - the page must never
   scroll sideways. */
.item-details__list {
    display: flex;
    flex-wrap: wrap;
    /* Edge-to-edge distribution (user 2026-08-09, third alignment
       iteration): first pair at the left edge, last at the right, the
       leftover space split EQUALLY between the pairs - the column gap
       below is only the minimum. */
    justify-content: space-between;
    gap: 0.3rem 2rem;
    margin: 0;
}

.item-details__pair {
    display: flex;
    align-items: baseline;
    gap: 0 0.4rem;
    min-width: 0;
    max-width: 100%;
}

.item-details__pair dt {
    color: var(--egun-text-muted);
    white-space: nowrap;
}

.item-details__pair dd {
    margin: 0;
    font-weight: 600;
    min-width: 0;
    overflow-wrap: anywhere;
}

.item-details__jump {
    font-weight: 400;
    white-space: nowrap;
}

.item-details__jump-arrow {
    font-size: 0.85em;
    margin-left: 0.1em;
}

/* Jump target of the strip's "(Details)" link - land below the sticky
   top bar instead of underneath it. */
.auction-shipping {
    scroll-margin-top: 4.5rem;
}

/* Share/recommend rows folded into the trade card (2026-08-09): same
   inset as the sibling action rows (bid/buy/watch), so all buttons in
   the stack share one width; the last row closes the card. */
.trade-card .trade-card__link-row {
    margin: 0;
    padding: 0 1rem 0.8rem;
}

.trade-card .trade-card__link-row:last-child {
    padding-bottom: 1rem;
}

/* "privater Verkäufer" badge (2026-07-19): same quiet pill as the
   gewerblich badge, but a BUTTON opening the EU-law popover - the
   :hover/:focus overrides shield it from the global button:hover fill
   (same load-bearing pattern as .disclosure-info). */
.badge--private,
.badge--private:hover,
.badge--private:focus {
    background: transparent;
    color: var(--egun-text-muted);
}

.badge--private {
    cursor: pointer;
}

.badge--private:hover {
    border-color: var(--egun-text-muted);
    color: var(--egun-text);
}

.auction-seller__member-since {
    margin: 0.1rem 0 0.5rem;
    color: var(--egun-text-muted);
}

/* Directly below the "% positive Bewertungen" line (user request
   2026-07-19): cancel the pct line's bottom margin so the two read as one
   reputation block - only when the pct line actually precedes it. */
.auction-seller__pct-line + .auction-seller__member-since {
    margin-top: -0.6rem;
}

/* --- Live-bid flash (2026-07-19): when the poll detects a new bid, the
   changed number gets a gold sweep (Kaufen world color) fading out, plus
   a tiny scale tick on the price - an auction "tick" the eye catches
   peripherally. Re-triggerable per change (class is re-applied by JS). --- */
.live-flash {
    display: inline-block;
    border-radius: 4px;
    animation: live-flash-bg 1.2s ease-out;
}

@keyframes live-flash-bg {
    0% { background-color: rgba(255, 204, 51, 0.55); }
    100% { background-color: transparent; }
}

@media (prefers-reduced-motion: no-preference) {
    .price__amount.live-flash {
        animation: live-flash-bg 1.2s ease-out, live-flash-tick 0.35s ease-out;
    }

    @keyframes live-flash-tick {
        0% { transform: scale(1); }
        35% { transform: scale(1.07); }
        100% { transform: scale(1); }
    }
}

/* --- /account: the three security sections (E-Mail, 2FA, Passkeys) as the
   SAME cards the page's fieldsets already are (2026-07-19, homogeneity). --- */
.profile-section {
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.8rem 1rem 1rem;
}

/* =============================================================
   Feature-gap batch, 2026-07-26: the four pages that until now
   existed only on the legacy desktop site. All four deliberately
   reuse the shapes already established elsewhere here - the card
   surface of .profile-section, the eyebrow headings, the quiet
   pills - rather than introducing a fifth list idiom. A page a
   user reaches twice a year should look like the rest of the app,
   not like it was designed separately.
   ============================================================= */

/* --- Meine schwarze Liste --- */
.blacklist {
    list-style: none;
    margin: 0.5rem 0 0;
    padding: 0;
    display: grid;
    gap: 0.6rem;
}
.blacklist__row {
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.7rem 0.9rem;
    display: grid;
    gap: 0.5rem;
}
.blacklist__who {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    flex-wrap: wrap;
}
/* A ban keyed on a nick nobody owns any more can never fire. Saying so
   is kinder than letting the seller believe they are still protected. */
.blacklist__gone {
    font-size: 0.78rem;
    color: var(--egun-text-muted);
    border: 1px solid var(--egun-border);
    border-radius: 999px;
    padding: 0.05rem 0.5rem;
}
.blacklist__comment {
    display: flex;
    gap: 0.4rem;
    align-items: center;
}
.blacklist__comment input[type="text"] {
    flex: 1 1 auto;
    min-width: 0;
}
.blacklist-add {
    margin-bottom: 1.2rem;
}

/* --- Letzte Geräte --- */
.device-list {
    list-style: none;
    margin: 0.5rem 0 0;
    padding: 0;
    display: grid;
    gap: 0.5rem;
}
.device-list__row {
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.65rem 0.9rem;
}
.device-list__meta {
    display: flex;
    gap: 0.75rem;
    flex-wrap: wrap;
    color: var(--egun-text-muted);
    font-size: 0.85rem;
    margin-top: 0.15rem;
}
.device-list__ip {
    font-variant-numeric: tabular-nums;
}

/* --- Gebotsliste --- */
.bid-history {
    list-style: none;
    margin: 0.5rem 0 0;
    padding: 0;
    display: grid;
    gap: 0.4rem;
}
.bid-history__row {
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 0.55rem 0.9rem;
    display: flex;
    flex-wrap: wrap;
    gap: 0.25rem 0.75rem;
    align-items: baseline;
}
.bid-history__who {
    font-weight: 600;
    flex: 1 1 40%;
    min-width: 0;
    overflow-wrap: anywhere;
}
/* Tabular figures so a column of amounts and timestamps lines up even
   though these are flex rows, not a table. */
.bid-history__amount,
.bid-history__when,
.bid-history__qty {
    font-variant-numeric: tabular-nums;
}
.bid-history__amount {
    font-weight: 600;
}
.bid-history__when,
.bid-history__qty {
    color: var(--egun-text-muted);
    font-size: 0.85rem;
}
/* Legacy paints this notice red ("redbold") and it earns it: it explains
   why every amount reads "–" while the auction runs. */
.bid-history__protected {
    color: var(--egun-red);
    font-weight: 600;
}

/* --- AGB-Zustimmung --- */
.terms-banner {
    background: var(--egun-surface);
    border: 1px solid var(--egun-gold);
    border-left: 4px solid var(--egun-gold);
    border-radius: var(--radius);
    padding: 0.8rem 1rem;
    margin-bottom: 1rem;
}
.terms-banner__text {
    margin: 0 0 0.4rem;
    font-weight: 600;
}
.terms-banner__deadline,
.terms-deadline {
    margin: 0 0 0.6rem;
    color: var(--egun-red);
    font-weight: 600;
}
/* The two answers must not look like a matched pair of buttons: accepting
   is routine, declining suspends the account. Separated by a rule and
   given the quiet secondary style, per the same reasoning as the
   destructive actions on /my-listings. */
.terms-decline {
    border-top: 1px solid var(--egun-border);
    padding-top: 0.8rem;
}

/* Admin impersonation bar (2026-07-28): sits above the sticky header,
   in the admin's red, and scrolls away with the page - it marks the
   session, it is not a control the member needs. Only ever rendered for
   an admin acting as a member (ROLE_IMPERSONATED_BY_ADMIN). */
.impersonation-bar {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    margin: 0;
    padding: 0.4rem 1rem;
    background: var(--egun-red);
    color: #fff;
    font-size: 0.88rem;
    font-weight: 600;
}

.impersonation-bar a,
.impersonation-bar a:hover {
    color: #fff;
    text-decoration: underline;
}

/* =====================================================================
   Print (2026-07-27). The pages worth printing are the booking pages -
   Kontoauszug, Rechnung Nr. N - and until now they printed with the
   sticky header, tab bar and footer stamped over the numbers. Print
   drops the chrome and the actions, keeps the content at full page
   width, and lets tables break naturally across pages. Lives in app.css
   (NOT desktop.css): printing must work from a phone with the desktop
   layer switched off. PDFs via wkhtmltopdf use their own templates and
   are untouched by this.
   ===================================================================== */
@media print {
    /* Chrome and screen-only apparatus. `button` covers every screen
       action (bid, toggle, submit) - on paper none of them exist. */
    .site-header,
    .ad-strip,
    .site-footer,
    .toast-stack,
    .pwa-install-banner,
    .pagination,
    .flash,
    button,
    .btn-quiet,
    .button-link {
        display: none !important;
    }

    body {
        background: #fff;
        color: #000;
        padding-bottom: 0;
    }

    .site-main {
        max-width: none;
        padding: 0;
    }

    a {
        color: inherit;
        text-decoration: none;
    }

    /* The statement's phone apparatus: the scroll box becomes plain
       flow (a page has no scrollbar), the compact font gets its print
       size back, and rows don't get sliced mid-line at a page break. */
    .statement-scroll {
        overflow: visible;
        border: none;
        border-radius: 0;
    }

    .statement-table {
        font-size: 10pt;
    }

    .statement-table tr,
    .statement-invoice,
    .invoice-card {
        break-inside: avoid;
    }

    /* Card surfaces print as hairline boxes, not gray fills. */
    .statement-invoice,
    .invoice-card,
    fieldset {
        background: #fff;
    }
}

/* Money readback under the sell/edit price fields (QA 2026-08-02) - the
   parsed interpretation of what was typed, e.g. "6.999" -> "= 6.999,00 €". */
.money-readback {
    display: block;
    margin-top: 0.25rem;
    color: var(--color-text-muted, #6b7280);
    font-variant-numeric: tabular-nums;
}

/* Error summary above the sell form (sell-flow audit 2026-08-02) - a
   rejected submit must be legible without scrolling three screens. */
.form-error-summary {
    border-left: 4px solid var(--color-danger, #b3261e);
    background: var(--color-danger-surface, #fdecea);
    color: var(--color-danger-text, #7f1d1d);
    padding: 0.85rem 1rem;
    margin: 0 0 1.25rem;
    border-radius: 0 var(--radius-sm, 6px) var(--radius-sm, 6px) 0;
}
.form-error-summary ul { margin: 0.5rem 0 0; padding-left: 1.15rem; }
.form-error-summary li { margin-bottom: 0.2rem; }
.form-error-summary a { color: inherit; }
.form-error-summary__images { margin: 0.6rem 0 0; font-size: 0.92em; }

/* Dunning banner (dashboard): legacy's mahn_remind lightbox as a card -
   the red sibling of .terms-banner, same anatomy. */
.dunning-banner {
    background: var(--egun-surface);
    border: 1px solid var(--egun-red, #c0392b);
    border-left: 4px solid var(--egun-red, #c0392b);
    border-radius: var(--radius);
    padding: 0.8rem 1rem;
    margin-bottom: 1rem;
}
.dunning-banner__text {
    margin: 0 0 0.4rem;
    font-weight: 600;
}
.dunning-banner__line {
    margin: 0 0 0.6rem;
    font-size: 0.9rem;
}

/* Seller-invoicing audit 2026-08-05: overdue pill + inline note-delete form */
.status-pill--danger {
    background: color-mix(in srgb, var(--egun-red, #c0392b) 14%, transparent);
    color: var(--egun-red, #c0392b);
    border-color: var(--egun-red, #c0392b);
}
.inline-form { display: inline; }

/* Registration/account audit 2026-08-05: pending email-change notice */
.notice {
    padding: 0.6rem 0.8rem;
    border: 1px solid var(--egun-gold, #c9a227);
    border-radius: 8px;
    background: color-mix(in srgb, var(--egun-gold, #c9a227) 12%, transparent);
    font-size: 0.9rem;
}

/* ------------------------------------------------------------------ */
/* Competitor-audit round 2026-08-08: search-filter hints, dealer     */
/* directory, accessibility statement, app-install promo.             */
/* ------------------------------------------------------------------ */

.filter-hint,
.form-hint {
    display: block;
    margin-top: 0.3rem;
    color: var(--egun-text-muted);
    font-size: 0.78rem;
}

/* Generic page eyebrow + lead (the dashboard/seller-stats device,
   available to any standalone page). */
.page-eyebrow {
    margin: 0 0 0.2rem;
    font-family: var(--font-display);
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--egun-text-muted);
}

.page-lead {
    color: var(--egun-text-muted);
    max-width: 46rem;
}

/* Händlerverzeichnis: ledger rows, most active first. */
.dealer-summary {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    color: var(--egun-text-muted);
    font-size: 0.9rem;
}

.dealer-list {
    list-style: none;
    margin: 1rem 0 0;
    padding: 0;
}

.dealer-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.65rem 0.25rem;
    border-bottom: 1px solid var(--egun-border);
}

.dealer-row__main {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    flex: 1 1 auto;
    min-width: 0;
    text-decoration: none;
    color: inherit;
}

.dealer-row__main:hover .dealer-row__nick {
    text-decoration: underline;
}

.dealer-row__nick {
    font-family: var(--font-display);
    font-weight: 600;
    overflow-wrap: anywhere;
}

.dealer-row__count {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 0.35rem;
    color: var(--egun-text-muted);
    font-size: 0.85rem;
    white-space: nowrap;
}

.accessibility-updated {
    margin-top: 1.5rem;
    color: var(--egun-text-muted);
    font-size: 0.85rem;
}

/* "eGun als App": phone shows the install button (JS reveals the section
   only when installation is actually possible); QR + scan hint are the
   desktop layer's variant of the same card. */
.app-promo {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    background: var(--egun-surface);
    border: 1px solid var(--egun-border);
    border-radius: var(--radius);
    padding: 1rem;
}

.app-promo__qr {
    display: none;
    flex: 0 0 auto;
    background: #fff;
    border: 1px solid var(--egun-border);
    border-radius: 6px;
    padding: 0.3rem;
}

.app-promo__text {
    min-width: 0;
}

.app-promo__text p {
    margin: 0 0 0.6rem;
}

.app-promo__scan {
    display: none;
    color: var(--egun-text-muted);
    font-size: 0.85rem;
}

.app-promo__ios-hint {
    color: var(--egun-text-muted);
    font-size: 0.85rem;
}

.app-promo__install {
    font: inherit;
    font-weight: 600;
    color: #fff;
    background: var(--egun-green, #1a8a3d);
    border: none;
    border-radius: 999px;
    padding: 0.5rem 1.1rem;
    cursor: pointer;
}

/* Stöbern dropdown wrapper: transparent for the phone's bottom tab bar
   (the desktop layer anchors the category panel to it). */
.tab-bar__browse {
    display: contents;
}

/* ------------------------------------------------------------------ */
/* Account menu (2026-08-09): identity header, the dashboard's four   */
/* worlds as sections, icon rows with live counts, separated logout.  */
/* One markup for the phone burger sheet AND the desktop dropdown.    */
/* ------------------------------------------------------------------ */

.acct-head {
    padding: 0.15rem 0.2rem 0.65rem;
    border-bottom: 1px solid var(--egun-border);
}

.acct-head__nick {
    margin: 0;
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.45rem;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 1.08rem;
    color: var(--egun-text);
    overflow-wrap: anywhere;
}

.acct-sections {
    display: grid;
    gap: 0.95rem;
    padding-top: 0.35rem;
}

.acct-section {
    display: flex;
    flex-direction: column;
    gap: 0.05rem;
}

.acct-section .dashboard-eyebrow {
    margin: 0 0 0.3rem;
}

/* Rows read in text color (the bare link blue turned the sheet into a
   wall of blue); the icon stays muted until hover. `a.` outweighs the
   generic .site-header__links a color above. */
a.acct-row {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    padding: 0.42rem 0.35rem;
    border-radius: 6px;
    color: var(--egun-text);
    text-decoration: none;
}

.acct-row svg {
    width: 1.05rem;
    height: 1.05rem;
    flex: none;
    color: var(--egun-text-muted);
}

.acct-row > span:first-of-type {
    flex: 1 1 auto;
    min-width: 0;
}

.acct-row:hover,
.acct-row:focus-visible {
    background: var(--egun-bg);
    text-decoration: none;
}

.acct-row:hover svg {
    color: var(--egun-text);
}

.acct-badge {
    flex: none;
    background: var(--egun-red);
    color: #fff;
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 700;
    line-height: 1.5;
    padding: 0 0.45rem;
}

a.acct-logout {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    margin-top: 0.55rem;
    padding: 0.55rem 0.35rem 0.15rem;
    border-top: 1px solid var(--egun-border);
    color: var(--egun-text-muted);
    text-decoration: none;
    font-weight: 600;
}

.acct-logout svg {
    width: 1.05rem;
    height: 1.05rem;
    flex: none;
}

a.acct-logout:hover,
a.acct-logout:focus-visible {
    color: var(--egun-red);
    text-decoration: none;
}

/* Suche innerhalb einer Kategorie (2026-08-18) - der Kasten sitzt
   zwischen H1 und Unterkategorien; die aktive-Suche-Zeile ist die
   Bestaetigung + der Ruecksetz-Link. */
.category-search {
    margin: 0.6rem 0 0.8rem;
}

.category-search__active {
    margin: -0.2rem 0 0.8rem;
    font-size: 0.85rem;
    color: var(--egun-text-muted);
}

/* Klassische-Ansicht-Hinweis (Migrations-Kohorte, 2026-08-18): ruhiger
   Block ganz oben im Inhalt - KEIN fixed overlay wie der Install-Banner,
   damit nie zwei schwebende Elemente konkurrieren (app.js verhindert
   zusaetzlich die gleichzeitige Anzeige). */
.classic-banner {
    margin: 0.6rem 0.8rem;
    padding: 0.7rem 0.9rem;
    border: 1px solid var(--egun-border);
    border-left: 3px solid var(--egun-blue);
    border-radius: var(--radius);
    background: var(--egun-surface);
    font-size: 0.9rem;
}

.classic-banner__text strong {
    display: block;
}

.classic-banner__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem 0.9rem;
    margin-top: 0.55rem;
}

/* contents statt inline: als Inline-Box war das FORM selbst das
   Flex-Item, und seine Zeilenbox (Grundlinie + Unterlaenge) schob
   den inneren Knopf aus der Mitte - beide Knoepfe standen sichtbar
   auf verschiedenen Hoehen (Nutzerreport 2026-08-18). Mit contents
   ist der Knopf selbst das zentrierte Flex-Item. */
.classic-banner__actions form {
    display: contents;
}

.classic-banner__actions a {
    font-size: 0.85rem;
}

/* "Verstanden" = der eine blaue Primaerknopf des Banners - btn-quiet-
   Masse, invertierte Farben (Nutzerwunsch 2026-08-18). */
.classic-banner__primary,
.classic-banner__primary.btn-quiet {
    background: var(--egun-blue);
    border-color: var(--egun-blue);
    color: #fff;
}

/* Menue-Eintrag "Klassische Ansicht" (2026-08-18): eigenstaendig
   definierte Fusszeilen-Zeile nach dem Muster von a.acct-logout -
   die Zeilen-Anatomie ist a.-qualifiziert, das <button> im POST-Form
   erbte davon nichts und stand als roher Browser-Knopf im Menue.
   Gedeckt + halbfett wie Abmelden (Meta-Aktion, keine Konto-Welt);
   Hover wechselt die Farbe wie bei den Fusszeilen (Welt-Zeilen
   bekommen Hintergrund, Fusszeilen nicht). Die Haarlinie zieht im
   Konto-Menue schon Abmelden; im Anon-Menue zieht diese Zeile sie
   selbst und laesst das Icon weg - die Zeilen dort tragen keine. */
.nav-classic {
    display: contents;
}

.nav-classic button {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    width: 100%;
    margin: 0;
    padding: 0.4rem 0.35rem 0.15rem;
    border: 0;
    background: none;
    font: inherit;
    font-weight: 600;
    color: var(--egun-text-muted);
    text-align: left;
    cursor: pointer;
}

.nav-classic button svg {
    width: 1.05rem;
    height: 1.05rem;
    flex: none;
}

.nav-classic button:hover,
.nav-classic button:focus-visible {
    color: var(--egun-text);
}

.site-header__links--anon .nav-classic button {
    margin-top: 0.55rem;
    /* 0 seitlich: die Anon-Links sitzen buendig am Panel-Rand, die
       0.35rem der Konto-Zeilen wuerden die Zeile sichtbar einruecken. */
    padding: 0.55rem 0 0.15rem;
    border-top: 1px solid var(--egun-border);
}

.site-header__links--anon .nav-classic button svg {
    display: none;
}
