/**
 * Noiz Template - Custom CSS
 * 
 * Custom overrides and plugin-specific styles
 */

/* Suspicious message warnings (from plugin) */
ul#messages_area .suspicious-msg .suspicious-message-warning {
    background-color: #ffdddd;
    border: 1px solid #ff5c5c;
    padding: 10px;
    margin-bottom: 15px;
    border-radius: 4px;
    color: #000000;
}

ul#messages_area li.suspicious-msg {
    border-color: #ff5c5c !important;
}

/* Multi-line listing titles override */
ul.featured.with-pictures ul.card-info > li.title a {
    white-space: normal !important;
    overflow: visible !important;
    text-overflow: clip !important;
    display: block !important;
    line-height: 1.3em;
    max-height: none;
    font-weight: 500;
}

article.item:not(.no-image) ul.card-info > li.title,
ul.featured.with-pictures ul.card-info > li.title {
    display: block !important;
    -webkit-line-clamp: unset !important;
    max-height: none !important;
    overflow: visible !important;
}

section#listings.grid > article:not(.no-image) ul.card-info > li.title {
    white-space: normal !important;
    overflow: visible !important;
    text-overflow: clip !important;
    display: block !important;
}

section#listings.list ul.card-info > li.title a {
    white-space: normal !important;
    overflow: visible !important;
    text-overflow: clip !important;
    display: block !important;
    line-height: 1.3em;
}

body.home-page .header-tabs { display: none; } 

div.gallery > #media[data-view="gallery"] .preview:not(.locked) + .map-container + .nav-buttons .nav-button.zoom, div.gallery > #media[data-view="gallery"] .preview:not(.locked) + .map-container + .nav-buttons .nav-button.map, div.gallery .nav-buttons .nav-button {
    background: var(--noiz-dark-orange);
    color: #ffffff !important;
}

.submission_instructions {
    font-size: 14px;
}

.submission_instructions a {
    color: var(--noiz-dark-orange);
}

.carousel-slide-heading { }
 
 .table-cell .checkboxes > *:not(.active) { display: none; }
 
 .carousel-caption .button { background-color:  var(--noiz-dark-orange) !important; }

/* Delete conversation button styles */
#messages_cont .delete-conversation {
    display: flex !important;
    align-items: center !important;
    gap: 8px !important;
    padding: 10px 16px !important;
    margin: 0 0 20px 0 !important;
    background: transparent !important;
    border: 1px solid #dc3545 !important;
    border-radius: 6px !important;
    color: #dc3545 !important;
    cursor: pointer !important;
    font-size: 14px !important;
    font-weight: 500 !important;
    transition: all 0.2s ease !important;
    white-space: nowrap !important;
    margin-left: auto !important;
    width: fit-content !important;
}

#messages_cont .delete-conversation:hover {
    background: #dc3545 !important;
    color: white !important;
}

#messages_cont .delete-conversation svg {
    flex-shrink: 0 !important;
}

#messages_cont .delete-conversation:hover svg {
    stroke: white !important;
}

#messages_cont ul#messages_area {
    clear: both !important;
}

.message-list-item {
    position: relative !important;
    display: flex !important;
    align-items: center !important;
}

.message-item-link {
    flex: 1 !important;
}

/* Individual message delete icon */
.message-sender-info {
    display: flex !important;
    align-items: center !important;
    gap: 10px !important;
}

.delete-message {
    cursor: pointer !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    padding: 4px !important;
    border-radius: 4px !important;
    transition: background 0.2s ease !important;
}

.delete-message:hover {
    background: rgba(220, 53, 69, 0.1) !important;
}

.delete-message svg {
    display: block !important;
}

/* =============================================
   LISTINGS COUNT - Below H1
   ============================================= */

.listings-count {
    font-size: 14px;
    margin-bottom: 16px;
    padding: 0 15px;
}

.listings-count .count-number {
    font-weight: 600;
}

/* =============================================
   GRID NAVBAR - Modern Rounded Style
   ============================================= */

/* Container - horizontal layout */
.grid_navbar.listings-area {
    display: flex;
    align-items: center;
    gap: 12px;
    height: auto;
    margin-top: 0;
    margin-bottom: 20px;
}

/* Switcher container - flex layout */
.grid_navbar .switcher {
    float: none;
    display: flex;
    align-items: center;
    height: auto;
    gap: 0;
}

/* View mode buttons container - rounded pill background */
.grid_navbar .switcher .buttons {
    display: flex;
    align-items: center;
    border-radius: 10px;
    padding: 4px;
    gap: 2px;
}

/* Individual view buttons */
.grid_navbar .buttons > div {
    position: relative;
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    border-radius: 8px;
    transition: background 0.2s ease;
}

.grid_navbar .buttons > div:hover {
    background: rgba(0, 0, 0, 0.05);
}

.grid_navbar .buttons > div.active {
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}

/* SVG icons for view modes */
.grid_navbar .buttons > div > svg {
    display: block;
    transition: color 0.2s ease;
}

.grid_navbar .buttons > div.active > svg,
.grid_navbar .buttons > div:hover > svg {
}

/* Grid navbar layout - right aligned actions */
.grid_navbar.listings-area {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 12px;
    flex-wrap: wrap;
}

.grid_navbar .hook {
    display: none;
}

/* Navbar actions container */
.grid_navbar .navbar-actions {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-left: auto;
}

/* Navbar buttons - Clear Filters & Save Search */
.navbar-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 14px;
    border-radius: 8px;
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    transition: all 0.2s ease;
    text-decoration: none;
    border: 1px solid transparent;
}

.navbar-btn svg {
    flex-shrink: 0;
}

/* Clear Filters Button */
.navbar-btn-clear {
    border: 1px solid transparent;
}

.navbar-btn-clear:hover {
    text-decoration: none;
}

/* Save Search Button */
.navbar-btn-save {
    border: 1px solid transparent;
}

.navbar-btn-save:hover {
}

/* Hide switcher wrapper styling, use buttons directly */
.grid_navbar .switcher {
    display: flex;
    align-items: center;
}


/* Sorting dropdown - rounded pill style */
.grid_navbar .sorting {
    position: relative;
    display: inline-flex;
    align-items: center;
    line-height: normal;
}

.grid_navbar .current {
    display: flex;
    align-items: center;
    gap: 6px;
    height: auto;
    padding: 10px 16px;
    border-radius: 10px;
    cursor: pointer;
    font-size: 14px;
    transition: background 0.2s ease;
    line-height: normal;
}

.grid_navbar .current .sort-icon {
    flex-shrink: 0;
}

.grid_navbar .current:hover {
}

.grid_navbar .current:hover .sort-icon {
}

.grid_navbar .current .link {
    font-size: 14px;
    font-weight: 600;
    text-transform: none;
    letter-spacing: 0;
    margin-left: 0;
}

.grid_navbar .sorting span.arrow {
    width: 12px;
    height: 12px;
    margin: 0 0 0 6px;
    background-size: contain;
    background-position: center;
}

/* Dropdown menu */
.grid_navbar ul.fields {
    top: calc(100% + 4px);
    left: auto;
    right: 0;
    border-radius: 10px;
    padding: 8px 0;
    min-width: 180px;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
    z-index: 100;
}

.grid_navbar ul.fields > li {
    padding: 8px 16px;
}

.grid_navbar ul.fields > li a {
    display: block;
    transition: color 0.2s ease;
}

.grid_navbar ul.fields > li a:hover,
.grid_navbar ul.fields > li a.active {
}

/* Hide filter hook on desktop (shown via mobile CSS) */
.grid_navbar .hook {
    display: none;
}

/* Responsive adjustments */
@media (max-width: 768px) {
    .grid_navbar.listings-area {
        justify-content: space-between;
    }
    
    .grid_navbar .current {
        padding: 8px 12px;
        font-size: 13px;
    }
    
    .grid_navbar .current .link {
        font-size: 13px;
    }
    
    .grid_navbar .buttons > div {
        width: 32px;
        height: 32px;
    }
    
    /* Show grid button on mobile - override original-style.css */
    .grid_navbar.listings-area .buttons > div.grid {
        display: flex !important;
    }
}
/* =============================================
   FILTERS AREA - Block position for categoryFilter
   ============================================= */

.filters-area {
    margin-bottom: 20px;
}

.filters-area .side_block {
    margin-bottom: 0;
}

.filters-area .side_block .content {
    padding: 0;
}

/* =============================================
   PAGINATION - Modern numbered pagination
   ============================================= */

.pagination-nav {
    display: flex;
    justify-content: center;
    margin: 30px 0;
}

.pagination-nav .pagination {
    display: flex;
    align-items: center;
    gap: 4px;
    list-style: none;
    padding: 0;
    margin: 0;
    flex-wrap: wrap;
    justify-content: center;
}

.pagination-nav .pagination-item {
    display: inline-flex;
    height: 36px;
}

.pagination-nav .pagination-link {
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: 36px;
    height: 36px;
    padding: 0 10px;
    border: 1px solid transparent;
    border-radius: 8px;
    font-size: 14px;
    font-weight: 500;
    text-decoration: none;
    transition: all 0.2s ease;
}

.pagination-nav .pagination-link:hover {
    text-decoration: none;
}

.pagination-nav .pagination-item.active .pagination-link {
    background: var(--noiz-dark-orange, #e67e22);
    border-color: var(--noiz-dark-orange, #e67e22);
    color: #fff;
}

.pagination-nav .pagination-ellipsis {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    vertical-align: middle;
    min-width: 36px;
    height: 36px;
    padding: 0 10px;
    border: 1px solid transparent;
    border-radius: 8px;
    font-size: 14px;
    font-weight: 500;
    position: relative;
    cursor: pointer;
    transition: all 0.2s ease;
}

.pagination-nav .pagination-ellipsis:hover {
}

.pagination-nav .pagination-ellipsis span {
    line-height: 1;
}

/* Pagination Jump Dropdown */
.pagination-jump-dropdown {
    display: none;
    position: absolute;
    bottom: calc(100% + 8px);
    left: 50%;
    transform: translateX(-50%);
    border: 1px solid transparent;
    border-radius: 10px;
    padding: 12px;
    z-index: 1000;
    min-width: 160px;
}

.pagination-jump-dropdown.open {
    display: block;
}

.pagination-jump-dropdown::after {
    content: '';
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
    border: 8px solid transparent;
}

.pagination-jump-dropdown::before {
    content: '';
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
    border: 9px solid transparent;
}

.pagination-jump-header {
    font-size: 12px;
    text-align: center;
    margin-bottom: 10px;
    font-weight: 500;
}

.pagination-jump-controls {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-bottom: 10px;
}

.pagination-jump-btn {
    width: 32px;
    height: 32px;
    border: 1px solid transparent;
    border-radius: 6px;
    font-size: 18px;
    font-weight: 500;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.15s ease;
    line-height: 1;
}

.pagination-jump-btn:hover {
}

.pagination-jump-btn:active {
}

.pagination-jump-input {
    flex: 1;
    height: 32px;
    border: 1px solid transparent;
    border-radius: 6px;
    text-align: center;
    font-size: 14px;
    font-weight: 500;
    width: 60px;
    -moz-appearance: textfield;
}

.pagination-jump-input::-webkit-outer-spin-button,
.pagination-jump-input::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

.pagination-jump-input:focus {
    outline: none;
    border-color: var(--noiz-dark-orange, #e67e22);
}

.pagination-jump-go {
    width: 100%;
    height: 34px;
    border: none;
    border-radius: 6px;
    background: var(--noiz-dark-orange, #e67e22);
    color: #fff;
    font-size: 13px;
    font-weight: 600;
    cursor: pointer;
    transition: all 0.15s ease;
}

.pagination-jump-go:hover {
    background: var(--noiz-light-orange, #f39c12);
}

.pagination-nav .pagination-prev .pagination-link,
.pagination-nav .pagination-next .pagination-link {
    gap: 6px;
    padding: 0 14px;
}

.pagination-nav .pagination-arrow {
    font-size: 18px;
    line-height: 1;
}

.pagination-nav .pagination-text {
    font-size: 13px;
}

/* Mobile responsive */
@media (max-width: 576px) {
    .pagination-nav .pagination {
        gap: 3px;
    }
    
    .pagination-nav .pagination-link {
        min-width: 32px;
        height: 32px;
        padding: 0 8px;
        font-size: 13px;
        border-radius: 6px;
    }
    
    .pagination-nav .pagination-text {
        display: none;
    }
    
    .pagination-nav .pagination-prev .pagination-link,
    .pagination-nav .pagination-next .pagination-link {
        padding: 0 10px;
    }
    
    .pagination-nav .pagination-ellipsis {
        min-width: 32px;
        height: 32px;
        padding: 0 8px;
        font-size: 13px;
        border-radius: 6px;
        margin-bottom: 4px;
    }
    
    .pagination-jump-dropdown {
        min-width: 140px;
        padding: 10px;
    }
    
    .pagination-jump-btn {
        width: 28px;
        height: 28px;
        font-size: 16px;
    }
    
    .pagination-jump-input {
        height: 28px;
        width: 50px;
        font-size: 13px;
    }
    
    .pagination-jump-go {
        height: 30px;
        font-size: 12px;
    }
}

/* Hide duplicate buttons from categoryFilter box - now in navbar */
.filter-area .cf-clear-all,
.filter-area .save-cf-search {
    display: none;
}

/* Responsive navbar actions */
@media (max-width: 768px) {
    .grid_navbar.listings-area {
        flex-wrap: wrap;
        gap: 8px;
    }
    
    .grid_navbar .navbar-actions {
        gap: 6px;
    }
    
    .navbar-btn {
        padding: 6px 10px;
        font-size: 12px;
    }
    
    .navbar-btn span {
        display: none;
    }
}

/* Mobile Grid View - 2 columns */
@media screen and (max-width: 767px) {
    section#listings.grid {
        display: flex;
        flex-wrap: wrap;
        margin: 0 -5px;
        padding: 0 15px;
    }
    
    section#listings.grid > article {
        flex: 0 0 50%;
        max-width: calc(50% - 10px);
        margin: 5px;
        padding: 0 0 20px 0;
    }
    
    section#listings.grid div.picture {
        width: 100%;
        height: auto;
        padding-bottom: 100%;
    }
    
    section#listings.grid ul.card-info {
        padding: 8px 0 0 0;
        width: 100%;
    }
    
    section#listings.grid ul.card-info > ol {
        display: none;
    }
    
    section#listings.grid ul.card-info > li.system {
        gap: 8px;
    }
}
/* ---------------------------------------------------------------------------
   Listing condition badge
   ---------------------------------------------------------------------------
   Condition used to render as another comma-separated value in li.fields,
   visually identical to the category. It is a primary buying signal for used
   gear (set on ~89% of listings), so it gets its own badge.

   Colours come from per-theme tokens in light.css / dark.css. Brand orange is
   deliberately avoided: it is the call-to-action colour, and reusing it for a
   passive attribute would weaken that signal.
--------------------------------------------------------------------------- */
/* The text colour is set on the <li>, not on the badge itself. A legacy rule
   `#listings .featured span { color: inherit }` carries an ID, so it outranks
   any class selector we could put on the span. Colouring the parent turns that
   forced inherit to our advantage and avoids !important. */
ul.card-info > li.condition {
    margin-top: 0.35rem;
    /* Tight underneath: the price sits directly below and carries 10px of its
       own padding, so anything more here reads as a gap between the badge and
       the price rather than the two belonging together. */
    margin-bottom: 0.125rem;
    color: var(--condition-badge-text);
}

.condition-badge {
    display: inline-flex;
    align-items: center;
    padding: 0.15em 0.6em;
    border: 1px solid var(--condition-badge-border);
    border-radius: 8px;              /* echoes the 12px thumbnail, scaled to a 25px chip */

    /* Outline, not filled. This chip carried --condition-badge-bg until the
       exchange chip landed beside it hollow and read better - lighter on a card
       that already has a photo, a title and a price competing for attention.
       The token is left defined in light.css / dark.css rather than removed;
       nothing else uses it, but it is the one place the fill would come back
       from if this is reverted. */
    background-color: transparent;

    color: inherit;
    font-size: 0.75em;               /* was 0.8125em (13px -> 12px) */
    font-weight: 300;                /* was 500; the chip reads as a label, not an emphasis */
    line-height: 1.45;
    white-space: nowrap;
}

/* Condition was briefly colour-coded per grade (gold/green/blue/grey/grey),
   reverted back to one neutral grey chip for every state. */

/* ---------------------------------------------------------------------------
   Listing card type scale
   ---------------------------------------------------------------------------
   Title was 17px/400 and price 20px/500, so the two competed. The price is now
   clearly the heavier element: on a marketplace grid it is what people scan.

   Weights stop at 600 on purpose - Onest ships Light/Regular/Medium/SemiBold
   only (300/400/500/600). Asking for 700 would give a synthesised faux-bold.

   !important appears on the title solely to override `.link-large`, which
   declares font-size and font-weight as !important in style.css.
--------------------------------------------------------------------------- */
/* The selector has to carry #listings: style.css sets
   `section#listings .link-large { font-size: 1.0625em !important }`, and an ID
   beats any number of classes, so a class-only rule silently loses on desktop
   even with !important. The second selector covers cards rendered outside
   #listings (the home page featured block). */
section#listings ul.card-info > li.title a,
ul.card-info > li.title a,
ul.card-info > li.title a.link-large {
    font-size: 1.125em !important;  /* 18px */
    font-weight: 500 !important;    /* Medium */
}

/* style.css drops titles to 1em on small screens; keep that. */
@media screen and (max-width: 767px) {
    section#listings ul.card-info > li.title a,
    ul.card-info > li.title a,
    ul.card-info > li.title a.link-large {
        font-size: 1em !important;
    }
}

ul.card-info > li.price_tag > div > span,
ul.card-info .price-tag > span {
    font-size: 1.4375em;            /* 23px */
    font-weight: 500;               /* Medium - the price leads on size, not weight */
}

/* ---------------------------------------------------------------------------
   Grid card layout
   ---------------------------------------------------------------------------
   1. Cards per row on wide screens.
   2. Pin the price to the bottom of the card.

   (1) went 5 -> 6 -> back to 5. At six the card carried the same five rows of
   text as a much wider card (title, condition, category, location/date,
   price) - the info block measured 79% of the image's own height, so text
   competed with the photo instead of sitting under it. At five it is 58%,
   and the photo leads. Dropping card rows was tried alongside this and
   reverted: the category and location/date both earn their place.

   On (2): the grid stretches every card in a row to the same height, but the
   card's content only filled its natural height, so the price landed wherever
   the text ended - 23px higher on a one-line title than a two-line one - and
   the leftover space sat below it. Making the column chain grow and pushing
   the price down with margin:auto aligns every price in a row and moves the
   slack above the price instead.
--------------------------------------------------------------------------- */
@media screen and (min-width: 1440px) {
    body.no-sidebar section.grid > article {
        flex: 0 0 20%;
        max-width: 20%;
    }
}

section#listings.grid article.item {
    display: flex;
    flex-direction: column;
}

section#listings.grid article.item > .main-column {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
}

section#listings.grid article.item ul.card-info {
    flex: 1 1 auto;
}

/* li.system holds the price row */
section#listings.grid article.item ul.card-info > li.system {
    margin-top: auto;
}

/* Home page featured blocks: match the category grid's per-row count above
   1440px. This is style.css's own default (20%), so nothing to override here
   any more - see the six-per-row note above for why it went there and back.
   The .two-middle layout keeps its own 33% rule regardless. */

/* Featured cards are already flex columns with a growing card-info, but the
   price still followed the text; push it down so prices share a baseline.
   Note the class differs between the two card templates: listing.tpl emits
   li.system, featured_item.tpl emits li.price_tag. */
ul.featured.with-pictures > li ul.card-info > li.system,
ul.featured.with-pictures > li ul.card-info > li.price_tag {
    margin-top: auto;
}

/* ---------------------------------------------------------------------------
   Reserve two lines for the card title
   ---------------------------------------------------------------------------
   With the price pinned to the bottom of the card, any variation in content
   height shows up as a gap above the price. Title length is what varies:
   across 100 home page cards, 46 titles ran to one line, 45 to two and 9 to
   three, and the gap above the price tracked that exactly (0-88px, median 23
   - one line).

   Reserving two lines makes the 91% that are one or two lines identical, so
   the gap disappears for them. Titles are deliberately not clamped, since a
   truncated model name loses real information on gear listings, so the 9 that
   run to three lines still sit one line lower.

   2 lines x 1.3 line-height x 1.125em (the 18px title against the 16px li).
--------------------------------------------------------------------------- */
/* No min-height here on purpose. Reserving two lines kept every card the
   same height, but on a one-line title the reserved line sat between the
   title and the condition badge and visibly detached them. The slack is
   better spent above the bottom-pinned price, where it reads as breathing
   room, so the title box is left at its natural height and simply capped at
   two lines by the clamp below. */

section#listings.grid article.item ul.card-info > li.title a,
ul.featured.with-pictures > li ul.card-info > li.title a {
    line-height: 1.3;
}

/* ---------------------------------------------------------------------------
   Clamp card titles to exactly two lines
   ---------------------------------------------------------------------------
   Paired with the min-height above, every card title now occupies exactly two
   lines, so cards are structurally identical and the gap above the price
   disappears - including the row effect, where one tall card lifted the gap
   for everything beside it.

   The trade-off is that ~9% of titles are truncated with an ellipsis. The full
   title remains in the link's title attribute and on the listing page.

   !important is required: earlier rules in this file deliberately un-clamped
   these titles (display:block, -webkit-line-clamp:unset, overflow:visible),
   so those have to be reversed explicitly.
--------------------------------------------------------------------------- */
section#listings.grid article.item ul.card-info > li.title a,
ul.featured.with-pictures > li ul.card-info > li.title a {
    display: -webkit-box !important;
    -webkit-line-clamp: 2 !important;
    -webkit-box-orient: vertical !important;
    overflow: hidden !important;
    text-overflow: ellipsis;
    line-height: 1.3;
    max-height: calc(2 * 1.3 * 1em);
}

/* ---------------------------------------------------------------------------
   EXPERIMENT: price directly under the condition
   ---------------------------------------------------------------------------
   Card order becomes: title, condition, price, category, location/date.

   Reordering is done with flex `order` rather than by moving markup, so this
   is one block to delete if it does not work out. card-info is already a flex
   column. The featured / new badges are left unordered, so they keep the
   default `order: 0` and stay above the title - which is where they sit in
   the stock template.

   Note the price can no longer be pinned to the bottom, so it sits wherever
   the title leaves it - prices no longer share a baseline across a row.
--------------------------------------------------------------------------- */
section#listings.grid article.item ul.card-info > li.title,
ul.featured.with-pictures > li ul.card-info > li.title { order: 1; }

section#listings.grid article.item ul.card-info > li.condition,
ul.featured.with-pictures > li ul.card-info > li.condition { order: 2; }

section#listings.grid article.item ul.card-info > li.system,
ul.featured.with-pictures > li ul.card-info > li.price_tag { order: 3; }

section#listings.grid article.item ul.card-info > li.fields,
ul.featured.with-pictures > li ul.card-info > li.fields { order: 4; }

/* Category sits below the price, not above the title.

   It was above the title on both card templates and, on home-page rows, the
   fields line printed it a second time below the price - the same fact twice
   on one card. The line below the price is the one that survives, so the
   ordering moves to match; the styling is untouched, which is what makes the
   surviving line look exactly like the one that used to sit above.

   Same order as li.fields on purpose: with Category_ID now skipped in that
   loop, the fields line is usually empty, and where it is not, the category
   still reads first because it comes first in the markup. */
section#listings.grid article.item ul.card-info > li.card-category,
ul.featured.with-pictures > li ul.card-info > li.card-category { order: 4; }

section#listings.grid article.item ul.card-info > li.useful,
ul.featured.with-pictures > li ul.card-info > li.useful { order: 5; }

/* Cancel the bottom pinning - the price is no longer the last row.
   The separation from the condition badge above comes almost entirely from
   this row's own 10px padding-top (style.css), so the margin here is kept
   minimal: at 0.375rem the badge and price read as two unrelated blocks
   rather than one price statement. */
section#listings.grid article.item ul.card-info > li.system,
ul.featured.with-pictures > li ul.card-info > li.system,
ul.featured.with-pictures > li ul.card-info > li.price_tag {
    margin-top: 0;
}

/* ---------------------------------------------------------------------------
   Price directly under the condition badge
   ---------------------------------------------------------------------------
   style.css sets `ul.card-info > li.price_tag > *:last-child { margin-top:
   15px }` - inherited from the layout where the price sat far down the card
   and needed separating from whatever was above it. With the price now
   straight after the condition badge that spacing reads as a gap rather than
   separation, so it is zeroed for both card templates.
--------------------------------------------------------------------------- */
section#listings.grid article.item ul.card-info > li.price_tag > *:last-child,
section#listings.grid article.item ul.card-info > li.system > *:last-child,
ul.featured.with-pictures > li ul.card-info > li.price_tag > *:last-child {
    margin-top: 0;
}


/* ---------------------------------------------------------------------------
   Footer - dark band
   ---------------------------------------------------------------------------
   Replaces the stock light-grey three-column footer: brand / links / app,
   closing with socials bottom-right.

   Dark in BOTH colour schemes - this is a deliberate brand surface, not a
   themed one, so the tones are stated outright rather than inherited. That
   means the footer needs its own light-on-dark text colours; it cannot borrow
   the page's, which flip with the theme.

   The inner container reuses .point1 (added in the markup) so the footer's
   width tracks the site's actual breakpoint ladder instead of a second,
   driftable copy of it - see .footer-inner below.
--------------------------------------------------------------------------- */
.page-footer {
    /* Built from the existing brand tokens (defined in light.css/dark.css) rather
       than new hex values, so the footer tracks the palette instead of drifting
       from it. Both are defined identically in light and dark, which is what makes
       an always-dark footer safe here. */
    --footer-bg-main: var(--noiz-black, #010101);
    --footer-text: #f5f5f5;
    --footer-muted: #a1a1a6;
    --footer-rule: rgba(255, 255, 255, 0.1);
    --footer-accent: var(--noiz-dark-orange, #ee6820);

    background: var(--footer-bg-main);
    color: var(--footer-muted);
    margin-top: 3rem;
    padding: 0;
}

.page-footer a {
    color: var(--footer-muted);
    text-decoration: none;
    transition: color 0.15s ease;
}

.page-footer a:hover,
.page-footer a:focus-visible {
    color: var(--footer-text);
    text-decoration: none;
}

/* Inner container.
   The footer must line up with the page above it at EVERY width, and the site
   container is not a single value - .point1 steps through 540px / 720px / 92vw /
   1110px / 93vw. So this reuses .point1 (added in the markup) for the ladder
   rather than restating it here, where it would silently drift the first time
   someone retunes a breakpoint. A fixed max-width was tried first and matched
   only around 1400px, going badly wrong on wide screens - at 1920 the page runs
   1786px while a 1110px footer sat marooned in the middle.

   .point1 supplies max-width only, so centring is added here. The 15px gutter is
   mirrored from .content-padding, which the rest of the site applies at <=767px
   only; above that the container is flush, so adding padding would push the
   footer 15px inboard of everything else. */
.footer-inner {
    width: 100%;
    margin-left: auto;
    margin-right: auto;
}

@media (max-width: 767px) {
    .footer-inner {
        padding-left: 15px;
        padding-right: 15px;
    }
}

/* --- Band: brand / links / app ------------------------------------------ */
.footer-main {
    padding: 3rem 0 1.5rem;
}

.footer-main-grid {
    display: grid;
    grid-template-columns: minmax(200px, 1fr) minmax(0, 2.2fr) minmax(180px, auto);
    gap: 2.5rem 3rem;
    align-items: start;
}

.footer-logo {
    display: inline-block;
    margin-bottom: 1rem;
}

/* logo-wordmark.png (957x235, ~4:1) is white-on-transparent artwork already made
   for a dark background, unlike the round mark used elsewhere on the site (a
   near-black disc that needs inverting to read here) - so no filter is needed,
   but the very wide aspect ratio means sizing by height alone would make it run
   wider than the brand column on narrow screens. max-width caps that instead. */
.footer-logo img {
    height: 44px;
    width: auto;
    max-width: 100%;
}

.footer-tagline {
    margin: 0;
    max-width: 32ch;
    font-size: 0.875rem;
    line-height: 1.5;
    color: var(--footer-muted);
}

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

.footer-link-col {
    margin: 0;
    padding: 0;
    list-style: none;
}

.footer-link-col li + li {
    margin-top: 0.6rem;
}

/* Column headings are the one place with real hierarchy - in the stock footer
   every link and heading shared a weight, so nothing read as a grouping. */
.footer-col-title {
    margin-bottom: 1rem;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--footer-text);
}

.footer-link-col a {
    font-size: 0.9rem;
}

.footer-app .footer-col-title {
    margin-bottom: 1rem;
}

.footer-app .mobile-apps {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
}

/* The PWA badge is injected by the PWA plugin as .pwa-install-button and is a
   black raster-ish badge that clashed badly with the site's type. Rather than
   replace it (the plugin binds its install handler to this element) it gets a
   neutral outlined frame so it reads as part of the footer. footer-forum-link
   shares that same frame treatment for visual consistency with the app badges
   above it. */
.page-footer .pwa-install-button,
.footer-store-link,
.footer-forum-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--footer-rule);
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.04);
    transition: border-color 0.15s ease, background-color 0.15s ease;
}

.page-footer .pwa-install-button:hover,
.footer-store-link:hover,
.footer-forum-link:hover {
    border-color: rgba(255, 255, 255, 0.28);
    background: rgba(255, 255, 255, 0.08);
}

.page-footer .pwa-install-button img,
.footer-store-link img {
    display: block;
    height: 32px;
    width: auto;
}

/* Sits below the app badges, not among them - full width of the app column
   rather than inline, and icon+label rather than icon-only like the store
   badges (those are internationally recognisable marks; the forum icon isn't,
   so it needs the text to actually communicate what it links to). */
.footer-forum-link {
    display: inline-flex;
    gap: 0.6rem;
    width: fit-content;
    margin-top: 0.75rem;
    padding: 0.65rem 1rem;   /* larger than the shared 0.5/0.75 - this badge carries a label, not just a mark */
}

/* forum-icon.svg is near-black artwork (like logo.svg) - see the note on
   .footer-logo img for why invert(1) is required rather than brightness(0)
   invert(1), which would flatten it to a blank shape on this background. */
.footer-forum-link img {
    display: block;
    height: 24px;
    width: 24px;
    filter: invert(1);
}

.footer-forum-link span {
    font-size: 1rem;
    font-weight: 500;
    color: var(--footer-text);
}

.footer-forum-link:hover span {
    color: var(--footer-accent);
}

/* --- Closing row: copyright left, socials hard right -------------------- */
.footer-bottom {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
    flex-wrap: wrap;
    margin-top: 3rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--footer-rule);
}

.footer-copy {
    font-size: 0.8125rem;
    color: var(--footer-muted);
}

.footer-copy a {
    text-decoration: underline;
    text-underline-offset: 2px;
}

.footer-socials {
    display: flex;
    align-items: center;
    gap: 1rem;
}

/* menus/footer_social_icons.tpl defaults each icon to Bootstrap's .ml-4
   (24px) unless marginClass is truthy - footer_data.tpl passes ''
   intending to opt out, but Smarty's {if $marginClass} treats an empty
   string as falsy, so the ml-4 default stays applied. That stacked on top
   of the flex gap put ~44px between 20px icons. Overridden here rather
   than editing the shared partial, which other pages also call. */
.footer-socials a {
    display: block;
    margin-left: 0 !important;
    color: var(--footer-muted);
}

.footer-socials svg {
    width: 20px;
    height: 20px;
    fill: currentColor;
}

.footer-socials a:hover {
    color: var(--footer-accent);
}

/* --- Responsive --------------------------------------------------------- */
@media (max-width: 991px) {
    .footer-main-grid {
        grid-template-columns: 1fr 1fr;
    }
    /* Brand spans the full width above the two remaining columns, otherwise the
       logo is stranded beside a single narrow link column. */
    .footer-brand {
        grid-column: 1 / -1;
    }
    /* .footer-links is already 2 columns at every width - nothing to override here. */
}

@media (max-width: 767px) {
    .footer-main-grid,
    .footer-links {
        grid-template-columns: 1fr;
    }
    .footer-main {
        padding: 2rem 0 1.25rem;
    }
    /* Socials above the fine print on narrow screens - reading order puts the
       useful thing first instead of trailing the legal line. */
    .footer-bottom {
        flex-direction: column;
        align-items: flex-start;
        margin-top: 2rem;
    }
    .footer-bottom .footer-socials {
        order: -1;
    }
}

/* ---------------------------------------------------------------------------
   Personalised feed ("based on what you viewed")
   ---------------------------------------------------------------------------
   One horizontally scrollable row of normal listing cards, with arrows.

   Native overflow rather than a carousel library: the bundled fancyapps build
   reports 0 slides even for its own documented markup, so its arrows rendered
   but scrolled nothing. Overflow also brings touch swipe and keyboard scrolling
   for free.
--------------------------------------------------------------------------- */
.personal-feed-scroller {
    position: relative;
}

/* The scroll viewport. Scrollbar is hidden because the arrows (and swipe) are
   the affordance; the row would otherwise show a permanent bar under the cards
   on platforms that reserve space for one. */
.personal-feed .personal-feed-body {
    overflow-x: auto;
    overflow-y: hidden;
    scroll-behavior: smooth;
    scrollbar-width: none;              /* Firefox */
    -ms-overflow-style: none;           /* legacy Edge */
    -webkit-overflow-scrolling: touch;
}

.personal-feed .personal-feed-body::-webkit-scrollbar {
    display: none;                      /* WebKit */
}

/* One non-wrapping line. `gap` is what puts air between the cards - the stock
   grid relies on Bootstrap column padding, which does nothing here because the
   row is flex rather than a .row of columns. */
.personal-feed .personal-feed-row {
    display: flex;
    flex-wrap: nowrap;
    gap: 20px;
    margin: 0;
}

/* Cards keep their Bootstrap column classes (col-sm-4 col-md-3) from
   listing.tpl, whose percentage widths are meant for a wrapping row and would
   otherwise fight the flex line. Width is set here instead, and shrinking is
   disabled so twelve cards stay full size and overflow rather than squashing
   to fit. */
.personal-feed .personal-feed-row > article.item {
    flex: 0 0 auto;
    width: calc((100% - 100px) / 6);    /* six across, minus the five 20px gaps */
    max-width: none;
    min-width: 170px;
    padding-left: 0;
    padding-right: 0;
    margin: 0;
}

/* Arrows, centred on the card artwork rather than the whole card - the title
   and price below would otherwise drag them visually off-centre. */
.personal-feed .personal-feed-nav {
    position: absolute;
    top: 90px;
    z-index: 3;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0;
    /* A hairline of page background separates the circle from a card it
       overlaps, so it reads as floating above the row rather than as part of
       whichever artwork happens to sit behind it. */
    border: 2px solid #ffffff;
    border-radius: 50%;
    background: var(--noiz-black, #010101);
    color: #ffffff;
    cursor: pointer;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.28);
    transition: background-color 0.15s ease, box-shadow 0.15s ease;
}

/* Brand orange on hover. The arrow stays white - it keeps contrast against
   both states, where switching the arrow colour instead would leave a dark
   glyph on a mid-orange disc. */
.personal-feed .personal-feed-nav:hover {
    background: var(--noiz-dark-orange, #ee6820);
    box-shadow: 0 3px 16px rgba(0, 0, 0, 0.34);
}

.personal-feed .personal-feed-nav svg {
    width: 20px;
    height: 20px;
}

/* Sit half-outside the row so they overlap the edge cards slightly, making it
   read as "there is more this way" rather than as page furniture. */
.personal-feed .personal-feed-nav.is-prev { left: -18px; }
.personal-feed .personal-feed-nav.is-next { right: -18px; }

/* [hidden] alone loses to display:flex above. */
.personal-feed .personal-feed-nav[hidden] {
    display: none;
}

@media (max-width: 1199px) {
    .personal-feed .personal-feed-row > article.item {
        width: calc((100% - 60px) / 4);
    }
}

@media (max-width: 767px) {
    /* The row element is section#listings.grid, reused from the stock listings
       markup, so two stock rules outrank anything selected by class alone here:

         section#listings.grid          -> flex-wrap: wrap
         section#listings.grid > article -> flex 0 0 50%, max-width calc(50% - 10px), margin 5px

       The first collapsed the scroller into a wrapping grid. The second, once
       combined with the min-width: 170px set above, left each card 180px wide
       inside a ~355px row - so exactly one fitted per line and the section
       rendered as twelve stacked rows of one card. Both need an ID in the
       selector to be beaten, hence #personal_feed rather than .personal-feed. */
    #personal_feed section.grid.personal-feed-row {
        flex-wrap: nowrap;
        gap: 12px;
        margin: 0;
    }

    /* Two cards across, with the third partly visible. That peek is what tells
       a touch user the row scrolls, since the arrows are hidden at this width.
       min-width has to be cleared explicitly: a min-width beats a max-width in
       CSS, so the 170px floor above would otherwise still win on a 360px phone
       no matter what width is set here. */
    #personal_feed .personal-feed-row > article.item {
        flex: 0 0 auto;
        width: 44%;
        max-width: none;
        min-width: 0;
        margin: 0;
    }
    /* Swipe is the natural gesture on touch; floating arrows over the cards
       would just cover artwork. */
    .personal-feed .personal-feed-nav {
        display: none;
    }
}

/* ===========================================================================
   Row scroller (shared component)
   ---------------------------------------------------------------------------
   Generic horizontal card row, used by the opted-in homepage listing boxes.
   Driven by noizRowScroller() in js/lib.js.

   The personalised feed still carries its own .personal-feed-* copy of this;
   it shipped first and is deliberately left alone here rather than refactored
   in the same change as a new rollout. Merging the two is a follow-up.
   =========================================================================== */
.row-scroller {
    position: relative;
}

.row-scroller__viewport {
    overflow-x: auto;
    overflow-y: hidden;
    scroll-behavior: smooth;
    scrollbar-width: none;              /* Firefox */
    -ms-overflow-style: none;           /* legacy Edge */
    -webkit-overflow-scrolling: touch;
}

.row-scroller__viewport::-webkit-scrollbar {
    display: none;                      /* WebKit */
}

/* The row keeps its Bootstrap .row class, which brings flex-wrap: wrap - the
   one thing a scroller cannot have. Class-only selectors are enough here: the
   cards are sized by .col-* utilities (specificity 0,1,0), not by an ID rule
   like the personal feed's section#listings.grid. */
.row-scroller__viewport > ul.featured {
    display: flex;
    flex-wrap: nowrap;
    gap: 20px;
    margin: 0;
    padding: 0;
}

/* Six across, matching "Με βάση αυτά που είδες" exactly - same widths, same
   breakpoints. These boxes used to be four across, which next to the feed read
   as two different grids on one page. The feed is the reference now, so the
   card sizes are shared rather than each row having its own idea. */
.row-scroller__viewport > ul.featured > li {
    flex: 0 0 auto;
    width: calc((100% - 100px) / 6);   /* six across, minus the five 20px gaps */
    max-width: none;
    min-width: 170px;
    margin: 0;
}

@media (max-width: 1199px) {
    .row-scroller__viewport > ul.featured > li {
        width: calc((100% - 60px) / 4);
    }
}

@media (max-width: 767px) {
    /* Two across with the third peeking, so a touch user can see it scrolls -
       the arrows are hidden at this width. This is where the component earns
       its keep: seven stacked cards become one swipeable line. */
    .row-scroller__viewport > ul.featured {
        gap: 12px;
    }
    .row-scroller__viewport > ul.featured > li {
        width: 44%;
        min-width: 0;
    }
}

/* Arrows. Same treatment as the feed's: black disc, white glyph, white ring so
   it separates from whatever artwork it overlaps. */
.row-scroller__nav {
    position: absolute;
    top: 90px;
    z-index: 3;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0;
    border: 2px solid #ffffff;
    border-radius: 50%;
    background: var(--noiz-black, #010101);
    color: #ffffff;
    cursor: pointer;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.28);
    transition: background-color 0.15s ease, box-shadow 0.15s ease;
}

.row-scroller__nav:hover {
    background: var(--noiz-dark-orange, #ee6820);
    box-shadow: 0 3px 16px rgba(0, 0, 0, 0.34);
}

.row-scroller__nav svg {
    width: 20px;
    height: 20px;
}

.row-scroller__nav.is-prev { left: -18px; }
.row-scroller__nav.is-next { right: -18px; }

/* [hidden] alone loses to display:flex above. */
.row-scroller__nav[hidden] {
    display: none;
}

@media (max-width: 767px) {
    /* Swipe is the natural gesture on touch, and floating arrows would just
       cover artwork. */
    .row-scroller__nav {
        display: none;
    }
}

/* Category and seller lines on listing cards.

   The selectors say section#listings, not section#listings.grid. These fields
   were once supplied only by the personalised feed, so the rules were scoped to
   the grid; they now render on every listing page, and the grid has three
   modes. In list mode none of this applied and the rating star - an SVG with no
   intrinsic size - expanded to fill its container, 545px of solid black on the
   recently-added page.

   The ordering rules further up stay grid-only on purpose: list mode lays its
   cards out differently and does not want the grid's column order. */
section#listings article.item ul.card-info > li.card-category,
ul.featured > li ul.card-info > li.card-category {
    margin: 0 0 4px;
    font-size: 13px;
    line-height: 1.3;
    /* Explicit, not var(--noiz-light-grey): that token is declared twice in
       the theme (#464646 and #c8c8c8) and the later one wins, so the
       fallback here never applied and this rendered at #c8c8c8 - about
       1.7:1 on a white card. #767676 is the intended grey and clears AA. */
    color: #767676;
}

section#listings article.item ul.card-info > li.card-category span,
ul.featured > li ul.card-info > li.card-category span {
    /* One line; a long Greek category name must not push the price down and
       leave the cards in the row at different heights. */
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/*
    Seller line, last row of the card.

    The ordering is kept separate from the appearance and stays grid-only. The
    grid card is a flex column whose rows are sequenced with `order`, not by DOM
    position: title 1, condition 2, price 3, fields/category 4, location 5.
    Anything without an explicit order defaults to 0 and jumps to the TOP -
    which is where this line landed at first, second from the top, despite being
    last in the markup. 10 rather than 6 so a row inserted later does not
    silently displace it.

    List mode does not use that column order and must not inherit it.
*/
section#listings.grid article.item ul.card-info > li.card-seller,
ul.featured > li ul.card-info > li.card-seller {
    order: 10;
}

/* Appearance applies in every grid mode - see the note above the category. */
section#listings article.item ul.card-info > li.card-seller,
ul.featured > li ul.card-info > li.card-seller {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-top: 6px;
    padding-top: 6px;
    border-top: 1px solid rgba(0, 0, 0, 0.06);
    font-size: 12px;
    font-weight: 300;
    line-height: 1.3;
    color: #767676;   /* same duplicate-token trap as the category line above */
}

/* The name yields the space: a long shop name must not push the rating off
   the card, since the rating is the smaller and more scannable of the two. */
section#listings article.item ul.card-info > li.card-seller .card-seller__name,
ul.featured > li ul.card-info > li.card-seller .card-seller__name {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

section#listings article.item ul.card-info > li.card-seller .card-seller__rating,
ul.featured > li ul.card-info > li.card-seller .card-seller__rating {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    flex: 0 0 auto;
    white-space: nowrap;
}

section#listings article.item ul.card-info > li.card-seller .card-seller__star,
ul.featured > li ul.card-info > li.card-seller .card-seller__star {
    width: 12px;
    height: 12px;
    fill: var(--noiz-yellow, #FFCF00);
}

section#listings article.item ul.card-info > li.card-seller .card-seller__votes,
ul.featured > li ul.card-info > li.card-seller .card-seller__votes {
    opacity: 0.75;
}

/* Price row sits directly under the condition badge, so its 10px padding-top
   from style.css was the largest part of the gap between them - bigger than
   either margin. 4px keeps the row clear of the badge without reading as a
   separation between two unrelated blocks. Only the grid card is touched; the
   list view keeps the original rhythm. */
section#listings.grid article.item ul.card-info > li.system {
    padding-top: 4px;
}

/* ---------------------------------------------------------------------------
   Box cards: identical metrics to the feed at every width.

   Two things had to be beaten here, and neither showed up at 1280px:

   1. style.css has
        body.no-sidebar aside:not(.two-middle) section:not(.side_block) .featured > li
        { flex: 0 0 20%; max-width: 20% }
      inside @media (min-width: 1440px). That is specificity (0,4,4) - far above
      a plain .row-scroller__viewport > ul.featured > li - and it sets
      flex-basis, which beats `width` outright. On a wide screen the boxes
      snapped to five across while the feed stayed at six.

   2. The cards keep Bootstrap's .row > * column padding (12px each side), which
      the feed's cards do not have. Same card width, smaller thumbnail inside.

   Hence the deliberately heavy selector and the explicit flex shorthand. The
   numbers are copied from the feed rather than re-derived, because "the same
   as the feed" is the actual requirement.
   ------------------------------------------------------------------------- */
body.no-sidebar .row-scroller.lb-scroller .row-scroller__viewport > ul.featured > li,
.row-scroller.lb-scroller .row-scroller__viewport > ul.featured > li {
    flex: 0 0 auto;
    width: calc((100% - 100px) / 6);   /* six across, minus the five 20px gaps */
    min-width: 170px;
    max-width: none;
    padding-left: 0;
    padding-right: 0;
}

@media (max-width: 1199px) {
    body.no-sidebar .row-scroller.lb-scroller .row-scroller__viewport > ul.featured > li,
    .row-scroller.lb-scroller .row-scroller__viewport > ul.featured > li {
        width: calc((100% - 60px) / 4);
    }
}

@media (max-width: 767px) {
    /* The feed's row is section#listings.grid, which carries 15px of side
       padding at this width; the box's ul has none. Both cards are 44%, but of
       different content boxes - 139px against 152px - and the rows started at
       different left edges. Matching the padding fixes both at once. */
    .row-scroller.lb-scroller .row-scroller__viewport > ul.featured {
        padding-left: 15px;
        padding-right: 15px;
    }

    body.no-sidebar .row-scroller.lb-scroller .row-scroller__viewport > ul.featured > li,
    .row-scroller.lb-scroller .row-scroller__viewport > ul.featured > li {
        width: 44%;
        min-width: 0;
        padding-left: 0;
        padding-right: 0;
    }
}

/* ---------------------------------------------------------------------------
   "Προβολή όλων" — the per-row link to the full listing page.

   Was a bare underlined anchor, which read as body text next to a section
   heading and, on mobile, as a stray line under the row. As a pill it reads as
   the one action the row offers, without competing with the cards: outlined
   rather than filled, because a solid brand button here would pull more
   attention than the listings it points at.
   ------------------------------------------------------------------------- */
.content_block.has-header-link > a.block-header-link {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 14px;
    border: 1px solid var(--highlight-border-color, #d4d4d4);
    border-radius: 999px;
    font-size: 14px;
    font-weight: 400;
    line-height: 1.2;
    text-decoration: none;
    white-space: nowrap;
    /* Theme-aware, not var(--noiz-black): that is a fixed near-black, so in
       dark mode the pill rendered black-on-dark and was effectively invisible.
       --body-font-color follows the theme (#111 light, #DADADA dark). The
       border token is likewise theme-aware. */
    color: var(--body-font-color, #111111);
    background: transparent;
    transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.content_block.has-header-link > a.block-header-link:hover,
.content_block.has-header-link > a.block-header-link:focus-visible {
    border-color: var(--noiz-dark-orange, #ee6820);
    background: var(--noiz-dark-orange, #ee6820);
    color: #ffffff;
    text-decoration: none;
}

.block-header-link__arrow {
    width: 15px;
    height: 15px;
    flex: 0 0 auto;
    /* Nudges forward on hover - the pill already signals "clickable", this
       signals "goes somewhere". */
    transition: transform 0.15s ease;
}

.content_block.has-header-link > a.block-header-link:hover .block-header-link__arrow {
    transform: translateX(2px);
}

@media (max-width: 767px) {
    /* Below the row on mobile (order-3), where a full-width pill would look
       like a form submit. Kept inline and centred instead. */
    .content_block.has-header-link > a.block-header-link {
        margin-top: 4px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .content_block.has-header-link > a.block-header-link,
    .block-header-link__arrow {
        transition: none;
    }
}

/* ---------------------------------------------------------------------------
   Chat attachments
   ------------------------------------------------------------------------- */
.chat-compose-actions {
    display: flex;
    align-items: center;
    gap: 10px;
}

.chat-media-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    padding: 0;
    border: 1px solid var(--highlight-border-color, #d4d4d4);
    border-radius: 50%;
    background: transparent;
    color: var(--body-font-color, #111111);
    cursor: pointer;
}

.chat-media-button:hover {
    border-color: var(--noiz-dark-orange, #ee6820);
    color: var(--noiz-dark-orange, #ee6820);
}

.chat-media-button svg { width: 18px; height: 18px; }

/* Queued-but-unsent attachments, above the send row. */
.chat-media-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 8px 0;
}

.chat-media-tile {
    position: relative;
    width: 72px;
    height: 72px;
    border-radius: 8px;
    overflow: hidden;
    background: var(--condition-badge-bg, #F4F4F6);
}

.chat-media-tile img,
.chat-media-tile video { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Pulses while the upload is in flight, so a large video does not look stuck. */
.chat-media-tile.is-uploading::after {
    content: '';
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg, rgba(0,0,0,0.05), rgba(0,0,0,0.14), rgba(0,0,0,0.05));
    animation: chatMediaPulse 1.1s ease-in-out infinite;
}

@keyframes chatMediaPulse { 0%,100% { opacity: .5 } 50% { opacity: 1 } }

@media (prefers-reduced-motion: reduce) {
    .chat-media-tile.is-uploading::after { animation: none; }
}

.chat-media-tile__remove {
    position: absolute;
    top: 2px;
    right: 2px;
    width: 20px;
    height: 20px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.6);
    color: #fff;
    font-size: 14px;
    line-height: 18px;
    cursor: pointer;
}

/* Sent attachments inside a message bubble. */
.message-media {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 6px;
}

.message-media__item {
    display: block;
    max-width: 240px;
    max-height: 240px;
    border-radius: 10px;
    overflow: hidden;
}

.message-media__item img,
video.message-media__item { max-width: 240px; max-height: 240px; border-radius: 10px; display: block; }

/* Chat image lightbox: the theme's modal, sized to the image rather than the
   other way round. max-height keeps a tall photo inside the viewport instead of
   pushing the modal off-screen, which is what a plain <img> does here. */
.chat-lightbox {
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Fills the modal box, which is sized in JS from the viewport. The image is
   contained inside it rather than the other way round - letting the photo
   dictate the box is what pushed the modal off-screen. */
.chat-lightbox {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
}

.chat-lightbox img {
    display: block;
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    object-fit: contain;
    border-radius: 8px;
}

/* Prev/next. Same black disc with a white glyph as the homepage row arrows, so
   the two read as one control vocabulary. Sat inside the image rather than
   outside it: the modal sizes to its content, so anything hung off the edges
   would be clipped on a narrow screen. */
.chat-lightbox__nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    padding: 0 0 3px;
    border: 2px solid #ffffff;
    border-radius: 50%;
    background: var(--noiz-black, #010101);
    color: #ffffff;
    font-size: 26px;
    line-height: 1;
    cursor: pointer;
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.35);
    transition: background-color 0.15s ease;
}

.chat-lightbox__nav:hover { background: var(--noiz-dark-orange, #ee6820); }
.chat-lightbox__nav.is-prev { left: 10px; }
.chat-lightbox__nav.is-next { right: 10px; }

/* Position counter, so it is obvious there is more than one and where you are. */
.chat-lightbox__count {
    position: absolute;
    left: 50%;
    bottom: 10px;
    transform: translateX(-50%);
    padding: 3px 10px;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.65);
    color: #fff;
    font-size: 12px;
    line-height: 1.4;
}

@media (max-width: 767px) {
    /* Swipe is not wired up, so the arrows have to stay - just smaller. */
    .chat-lightbox__nav { width: 34px; height: 34px; font-size: 22px; }
    .chat-lightbox__nav.is-prev { left: 4px; }
    .chat-lightbox__nav.is-next { right: 4px; }
}

@media (prefers-reduced-motion: reduce) {
    .chat-lightbox__nav { transition: none; }
}

/* The sent thumbnail should read as clickable. */
a.message-media__item { cursor: zoom-in; }

/* ---------------------------------------------------------------------------
   Chat video: poster tile in the bubble, real playback in the lightbox.
   ------------------------------------------------------------------------- */
a.message-media__item.is-video {
    position: relative;
    display: block;
    width: 240px;
    max-width: 100%;
    aspect-ratio: 4 / 3;
    border-radius: 10px;
    overflow: hidden;
    background: #000;
    cursor: pointer;
}

a.message-media__item.is-video video {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    /* The tile is the button; the frame underneath must not swallow the click
       or take keyboard focus of its own. */
    pointer-events: none;
}

/* Play badge, centred over the frame. */
.message-media__play {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #fff;
}

.message-media__play svg {
    width: 54px;
    height: 54px;
    padding: 12px;
    border-radius: 50%;
    background: rgba(0, 0, 0, 0.55);
    box-shadow: 0 2px 14px rgba(0, 0, 0, 0.4);
    transition: background-color 0.15s ease, transform 0.15s ease;
}

a.message-media__item.is-video:hover .message-media__play svg {
    background: var(--noiz-dark-orange, #ee6820);
    transform: scale(1.06);
}

/* In the lightbox the video gets the whole box, controls and all. */
.chat-lightbox.is-video video {
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    border-radius: 8px;
    background: #000;
}

@media (prefers-reduced-motion: reduce) {
    .message-media__play svg { transition: none; }
}

/* ==========================================================================
   SYSTEM NOTICES
   ==========================================================================
   Replaces the stock notice panel, which was dropped over the top of the page
   and on the home page landed in the middle of the hero image.

   The strip is a dark surface in both themes rather than a themed one. Light
   and dark here are two stylesheets redefining the same :root variables, and a
   notice built out of those variables is the exact shape of the earlier
   "Προβολή όλων" bug - a colour that reads correctly in one theme and vanishes
   in the other. A dark bar with light text is legible under both, and it is
   what a transient message looks like on every other site the visitor uses.

   Colour carries the type, but never alone: each type also has its own icon,
   so the difference survives a monochrome display or a red-green deficiency.
   ========================================================================== */

.noiz-notice {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;

    /* Above the highest z-index in the template (10000, the modal mask): a
       message about a failed action must not appear behind the dialog that
       caused it. */
    z-index: 10001;

    background: #16171a;
    color: #f4f4f5;
    box-shadow: 0 -8px 28px -8px rgba(0, 0, 0, 0.45);

    /* Sits off-screen until .is-visible. Transitioning transform rather than
       `bottom` keeps the animation on the compositor. */
    transform: translateY(100%);
    transition: transform 0.28s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.noiz-notice.is-visible {
    transform: translateY(0);
}

.noiz-notice__inner {
    display: flex;
    align-items: flex-start;
    gap: 14px;

    max-width: 1280px;
    margin: 0 auto;

    /* The bottom padding clears the iOS home indicator, which sits over the
       strip in the installed web app. env() resolves to zero everywhere else,
       hence the max() rather than a plain addition. */
    padding: 15px 24px;
    padding-bottom: max(15px, env(safe-area-inset-bottom, 0px));
}

.noiz-notice__icon {
    flex: 0 0 auto;
    display: block;
    width: 21px;
    height: 21px;

    /* Optical alignment with the first line of text rather than the box. */
    margin-top: 1px;
}

.noiz-notice__icon svg {
    display: block;
    width: 100%;
    height: 100%;
}

.noiz-notice__text {
    flex: 1 1 auto;
    min-width: 0;          /* lets a long unbroken string wrap instead of pushing the close button off */
    font-size: 0.95rem;
    line-height: 1.55;
    word-wrap: break-word;
}

.noiz-notice__text a {
    color: var(--noiz-light-orange, #ff8200);
    text-decoration: underline;
}

/* Validation errors arrive as a list. A single one reads better without a
   bullet hanging off the side of it. */
.noiz-notice__text ul {
    margin: 0;
    padding: 0 0 0 18px;
}

/* The bullet has to be set on the item, not the list: the template's reset
   clears list-style on every li, and that beats a value inherited from the ul.
   The stock notice styled its items for the same reason. */
.noiz-notice__text ul > li {
    list-style: disc;
}

.noiz-notice__text ul > li + li {
    padding-top: 4px;
}

.noiz-notice__text ul > li:only-child {
    list-style: none;
    margin-left: -18px;
}

.noiz-notice__close {
    position: relative;    /* containing block for the two strokes below */
    flex: 0 0 auto;
    width: 30px;
    height: 30px;
    margin: -4px -6px 0 0;
    padding: 0;

    border: 0;
    border-radius: 50%;
    background: transparent;
    color: #a1a1aa;
    cursor: pointer;
    transition: background-color 0.15s ease, color 0.15s ease;
}

/* Drawn rather than a glyph: the multiplication sign renders at a different
   weight and baseline in every font on the stack. */
.noiz-notice__close::before,
.noiz-notice__close::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 13px;
    height: 1.5px;
    background: currentColor;
    border-radius: 1px;
}

.noiz-notice__close::before {
    transform: translate(-50%, -50%) rotate(45deg);
}

.noiz-notice__close::after {
    transform: translate(-50%, -50%) rotate(-45deg);
}


.noiz-notice__close:hover {
    background: rgba(255, 255, 255, 0.1);
    color: #ffffff;
}

.noiz-notice__close:focus-visible {
    outline: 2px solid var(--noiz-light-orange, #ff8200);
    outline-offset: 2px;
}

/* --- types ---------------------------------------------------------------
   A hairline in the type colour along the top edge, so the kind of message is
   readable from the shape of the bar before the icon is looked at. */
.noiz-notice::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 3px;
    background: currentColor;
}

.noiz-notice--notice  { color: #4ade80; }
.noiz-notice--warning { color: #fbbf24; }
.noiz-notice--error   { color: #f87171; }

/* The type colour belongs to the icon and the hairline. The message itself
   stays near-white - coloured body text on a dark bar is harder to read, and
   the two accents already carry the meaning. */
.noiz-notice__text {
    color: #f4f4f5;
}

@media (max-width: 767px) {
    .noiz-notice__inner {
        gap: 11px;
        padding: 13px 16px;
        padding-bottom: max(13px, env(safe-area-inset-bottom, 0px));
    }

    .noiz-notice__text {
        font-size: 0.9rem;
    }
}

@media (prefers-reduced-motion: reduce) {
    .noiz-notice {
        transition: none;
    }
}

/* ==========================================================================
   SITE-WIDE LISTING GRID DENSITY
   ==========================================================================
   Category pages, search results and recently-added rendered four cards to a
   row while the home page rendered six, so the same card design read as two
   different grids depending on where you were. These bring the section grid to
   the home page's density and breakpoints.

   The width comes from Bootstrap's .col-md-3 (25%) on article.item, so the
   override needs to beat a plain class selector. section#listings.grid already
   carries an ID, which is enough - the same reason #personal_feed was needed
   when the feed was built.

   Breakpoints mirror the row scroller exactly rather than approximately: six
   across on desktop, four on laptops, three on tablets, two on phones. Where
   they disagreed before, a card changed size when crossing between the home
   page and a category page.
   ========================================================================== */

@media (min-width: 1200px) {
    section#listings.grid > article.item {
        flex: 0 0 16.6667%;
        max-width: 16.6667%;
    }
}

@media (min-width: 992px) and (max-width: 1199px) {
    section#listings.grid > article.item {
        flex: 0 0 25%;
        max-width: 25%;
    }
}

@media (min-width: 768px) and (max-width: 991px) {
    section#listings.grid > article.item {
        flex: 0 0 33.3333%;
        max-width: 33.3333%;
    }
}

/* Phones keep the stock two-across. The scroller's 44% peek is deliberate for a
   horizontal row - it hints that there is more sideways. A wrapping grid has no
   sideways, so a peek there would just be a clipped card. */

/* ==========================================================================
   "ACCEPTS EXCHANGE" BADGE
   ==========================================================================
   Sits beside the condition chip on the card, because it answers a related
   question about the same item - what state it is in, and how you can get it.

   Deliberately quieter than the condition badge: outline only, no fill. The
   condition applies to every listing and is the primary chip; exchange applies
   to about one in fourteen and is a bonus. Two identically-weighted chips side
   by side would compete, and the eye would stop reading either as primary.

   It borrows the condition badge's geometry exactly - same padding, radius,
   size and weight - so the pair reads as one unit rather than two components
   that happen to be adjacent.
   ========================================================================== */

.exchange-badge {
    display: inline-flex;
    align-items: center;
    margin-left: 5px;
    padding: 0.15em 0.6em;
    border: 1px solid var(--condition-badge-border);
    border-radius: 8px;

    /* Outline, same as the condition chip beside it. The two are deliberately
       identical in treatment and told apart by their words alone - one names a
       state, the other names a possibility, and neither outranks the other. */
    background-color: transparent;

    /* No colour of its own on purpose. Brand orange was the obvious choice and
       is the wrong one - the note above this section already settled that it is
       the call-to-action colour and spending it on a passive attribute weakens
       the signal. It also could not have worked: a legacy
       `#listings .featured span { color: inherit }` carries an ID and beats any
       class selector here, which is why the condition chip colours its parent
       <li> instead. That trick does not extend to a second chip needing a
       different colour, so this one inherits the same grey - which is now the
       intended look for both rather than a constraint worked around. */

    font-size: 0.75em;
    font-weight: 300;
    line-height: 1.45;
    white-space: nowrap;
}

/* The row holding both chips needs to wrap rather than overflow: at 170px the
   two together are wider than the card, and without this the second one is
   clipped at the edge instead of dropping to the next line. */
ul.card-info > li.condition {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 0;
    align-items: center;
}

/* The gap above supplies the spacing when they wrap onto separate lines;
   margin-left would then indent the second chip for no reason. */
ul.card-info > li.condition .exchange-badge:first-child {
    margin-left: 0;
}
