/**
 * 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;
}

/*
    The number is not emphasised.

    It carried font-weight 600 while the word beside it did not, so
    "2,448 Καταχωρίσεις" read as two typefaces in one four-word line. The
    count is context, not a headline - the h1 above it is already doing that
    job. Kept as a rule rather than deleted so the reasoning survives.

    Dropping the weight was not enough, because the emphasis was in two
    places. light.css:384 also paints the number #333 against the #666 of the
    word beside it, and dark.css:748 does the same with #f1f5f9 against
    #9ca3af - a contrast step large enough to read as a heavier face even
    once the weights match. A computed-style diff was what found it: the font
    shorthand was already identical on both, and every one of the seventeen
    differences was colour.

    `inherit` rather than a literal, because the two theme sheets are mutually
    exclusive - one of them is disabled outright - so custom.css cannot name a
    colour per theme. Taking the parent value gets #666 under light and
    #9ca3af under dark from one rule. The overrides in light.css and dark.css
    are left where they are; custom.css loads after both and equal specificity
    then falls to order.
*/
.listings-count .count-number {
    font-weight: inherit;
    color: inherit;
}

/* =============================================
   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;
    }
}

/*
    Save Search is hidden here because the toolbar carries it. Clear filters
    is NOT, any more.

    Both used to be hidden: the toolbar held a copy of each, so categoryFilter
    box's originals were suppressed. The clear-filters copy has been removed
    from the toolbar and .cf-clear-all is once again the only one, at the end
    of the chip row where the filters it clears actually are - so hiding it
    now would leave no way to clear anything.

    .filter-area is an ANCESTOR of .cf-filters-row, not its parent, which is
    why this descendant selector reached the link at all. Worth knowing before
    reading it as dead code: it is easy to check the immediate parent, see
    .cf-filters-row, and conclude the rule never matched.
*/
.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 ------------------------------------------ */
/*
    THE PADDING HERE HAS TO CARRY .page-footer, OR IT DOES NOTHING.

    This rule used to say `.footer-main { padding: 3rem 0 1.5rem }` and had
    never applied: style.css owns the footer's vertical space through
    `.page-footer > div` at (0,1,1), which beats a bare class, and sets 36px top
    and bottom - with media variants going to 48px bottom below 1200. Reading
    the computed style is what surfaced it; the declaration looked live and was
    not.

    Top stays at the 36px the footer has always had. The bottom drops to 14px:
    it sits under the closing row, which now has its own trimmed spacing, and
    the two together left a band of empty dark below the last line on the page.
*/
.page-footer > div.footer-main {
    padding: 36px 0 14px;
}

.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 {
    /* 38, down from 44. The wordmark is the widest thing in the brand column
       and at 44 it set the column's rhythm rather than sitting inside it. */
    height: 38px;
    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 -------------------- */
/*
    The closing row - copyright and social icons - carries one line of text and
    a row of 20px icons, and had 3rem above the rule plus 1.5rem below it. That
    is more vertical space than the content in it, on the least important band
    of the page.

    Halved above and trimmed below; the rule still separates it from the
    columns, which is the part doing the work.
*/
.footer-bottom {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1.5rem;
    flex-wrap: wrap;
    margin-top: 1.5rem;
    padding-top: 1rem;
    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;
    }
    /* Same reasoning as the base rule - the selector needs .page-footer to
       beat style.css, which pushes the bottom to 48px at this width. */
    .page-footer > div.footer-main {
        padding: 32px 0 12px;
    }
    /* 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. */
/*
    THE ID IS REQUIRED, AND SO IS FLEX-BASIS.

    Two separate traps, both measured rather than reasoned about after the feed's
    cards turned out 223px wide against 206px everywhere else:

    1. The row element is section#listings.grid, reused from the stock listings
       markup, and the site-wide grid block further down this file sets
       `section#listings.grid > article.item { flex: 0 0 16.6667% }`. That
       carries an ID, so a class-only selector here loses however specific it
       looks. The mobile block below already hit this and fixed it the same way;
       these two rules predate that block and were quietly overridden when it
       landed.

    2. Setting `width` was not enough. These are flex items, and flex-basis wins
       over width - so the losing rule's 16.6667% basis decided the size while
       this rule's width sat there computing correctly and doing nothing.

    16.6667% is right on a wrapping grid, which has no gaps. Inside a flex row
    with a 20px gap it is one gap too wide per card, which is the whole
    discrepancy: (100% - 100px) / 6 is the same six-across arithmetic the row
    scroller uses.
*/
#personal_feed section.grid.personal-feed-row > article.item {
    flex: 0 0 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) {
    /* Same ID and same flex-basis reasoning as the desktop rule above: the
       site-wide grid sets 25% here, which is a gap too wide for a flex row. */
    #personal_feed section.grid.personal-feed-row > article.item {
        flex: 0 0 calc((100% - 60px) / 4);
        max-width: none;
    }
}

@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;
    /* Wraps so the hint can drop to its own line on a narrow screen; without
       this the mobile rule below has nowhere to put it. */
    flex-wrap: wrap;
    gap: 10px;
}

/* A paperclip on its own is only discoverable to someone already looking for
   one, and nothing announced that the conversation takes audio at all. The
   control is now a labelled pill in the brand colour, sitting next to a line
   naming what it accepts. */
.chat-media-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    height: 38px;
    padding: 0 14px;
    border: 1px solid var(--noiz-dark-orange, #ee6820);
    border-radius: 999px;
    background: transparent;
    color: var(--noiz-dark-orange, #ee6820);
    font-size: 0.875rem;
    font-weight: 400;
    line-height: 1;
    cursor: pointer;
    transition: background-color 0.15s ease, color 0.15s ease;
}

/* Fills on hover rather than only changing colour: the outline state already
   uses the brand colour, so a hover that only shifted hue would be invisible. */
.chat-media-button:hover,
.chat-media-button:focus-visible {
    background: var(--noiz-dark-orange, #ee6820);
    color: #ffffff;
}

.chat-media-button:focus-visible {
    outline: 2px solid var(--noiz-dark-orange, #ee6820);
    outline-offset: 2px;
}

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

.chat-media-button__label { white-space: nowrap; }

/* What the button accepts, stated once beside it. Muted: it answers a question
   the visitor has on first use and should not compete with the send button
   afterwards. */
/*
    Sits under the attach button on its own line rather than beside it - it is a
    sentence now, and on the same row it either squeezed the button or wrapped
    raggedly depending on the viewport.

    align-self, not text-align. div.send-controls is a flex column with
    align-items: center, and its buttons only look left-aligned because
    "div.send-controls > div { width: 100% }" stretches them - a rule that
    selects div and therefore skips this span. So the span stays shrink-wrapped
    and gets centred as a flex item, and no amount of text-align inside a box
    that is itself centred would move it.

    flex-start rather than a fixed side: on the cross axis of a column it
    follows the inline direction, so the RTL stylesheet needs no counterpart.

    max-width stops the sentence running the full width of a desktop
    conversation, where one unbroken line would be far wider than the buttons it
    describes.
*/
.chat-media-hint {
    display: block;
    align-self: flex-start;
    margin-top: 8px;
    max-width: 46ch;
    font-size: 0.8125rem;
    line-height: 1.35;
    opacity: 0.7;
}

/* On a phone the compose row is tight. The icon keeps its meaning without the
   word next to it, and the hint carries the detail underneath. */
@media (max-width: 575px) {
    .chat-media-button {
        gap: 0;
        width: 38px;
        padding: 0;
        border-radius: 50%;
    }

    .chat-media-button__label {
        display: none;
    }

    .chat-media-hint {
        flex-basis: 100%;
        order: 10;
        margin-top: 6px;
        font-size: 0.75rem;
    }
}

/* 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; }
}

/* An audio attachment has nothing to show as a thumbnail. It used to fall
   through to the <video> branch, which renders a zero-height black box for a
   file with no video track - an attachment that looked like a failed upload.
   A speaker glyph on the tile background says "sound" without pretending to be
   a preview. */
.chat-media-tile.is-audio {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--noiz-dark-orange, #ee6820);
}

.chat-media-tile.is-audio svg { width: 30px; height: 30px; }

.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;
}

/* ---------------------------------------------------------------------------
   Voice recording

   One control on its own row above the attach button. Press to start, press
   again to stop and send - so the button has to carry its own running state
   rather than handing it to a separate strip.
   --------------------------------------------------------------------------- */
/* A column, so the "new feature" line sits under the button rather than beside
   it, and align-items keeps both pinned left - send-controls centres its
   children, which is what put the attach hint in the middle of the page. */
.chat-compose-voice {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
    margin-bottom: 10px;
}

/* Quieter than the button and the same size as the attach hint below it, so the
   two read as one register rather than competing. The brand colour rather than
   grey: it is an announcement, and it is the only thing on the page that has
   anything to announce. */
.chat-voice-new {
    max-width: 46ch;
    font-size: 0.8125rem;
    line-height: 1.35;
    color: var(--noiz-dark-orange, #ee6820);
}

.chat-voice-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    height: 38px;
    padding: 0 14px;
    border: 1px solid var(--noiz-dark-orange, #ee6820);
    border-radius: 999px;
    background: transparent;
    color: var(--noiz-dark-orange, #ee6820);
    font-size: 0.875rem;
    line-height: 1;
    cursor: pointer;
    transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.chat-voice-button:hover,
.chat-voice-button:focus-visible {
    background: var(--noiz-dark-orange, #ee6820);
    color: #ffffff;
}

.chat-voice-button:focus-visible {
    outline: 2px solid var(--noiz-dark-orange, #ee6820);
    outline-offset: 2px;
}

.chat-voice-button svg { width: 18px; height: 18px; flex: 0 0 auto; }

.chat-voice-button__label { white-space: nowrap; }

/* Tabular figures so ticking seconds do not change the button's width. */
.chat-voice-button__time {
    font-variant-numeric: tabular-nums;
    opacity: 0.85;
}

.chat-voice-button__time:empty { display: none; }

/* Recording. Red rather than the brand orange, and filled rather than outlined:
   this is the one control on the page that means "your microphone is live", and
   wearing the same colour as every other button would read as just another
   action. The hover rule above is overridden so it does not flip back to orange
   under the cursor. */
.chat-voice-button.is-recording,
.chat-voice-button.is-recording:hover,
.chat-voice-button.is-recording:focus-visible {
    border-color: #d92d20;
    background: #d92d20;
    color: #ffffff;
}

/* The dot only exists while recording - the resting button is label and mic
   glyph alone. */
.chat-voice-button__dot { display: none; }

.chat-voice-button.is-recording .chat-voice-button__dot {
    display: block;
    width: 9px;
    height: 9px;
    flex: 0 0 auto;
    border-radius: 50%;
    background: #ffffff;
    animation: chatVoicePulse 1.2s ease-in-out infinite;
}

/* The whole button breathes as well, so the running state is legible from
   across the page and not only from the small dot. */
.chat-voice-button.is-recording {
    animation: chatVoiceGlow 1.8s ease-in-out infinite;
}

@keyframes chatVoicePulse { 0%, 100% { opacity: 1 } 50% { opacity: 0.2 } }

@keyframes chatVoiceGlow {
    0%, 100% { box-shadow: 0 0 0 0 rgba(217, 45, 32, 0.45) }
    50%      { box-shadow: 0 0 0 6px rgba(217, 45, 32, 0) }
}

/* Motion is the signal here, so when it is suppressed the state still has to
   read: the dot stays solid rather than stopping mid-fade, and the colour
   change carries it on its own. */
@media (prefers-reduced-motion: reduce) {
    .chat-voice-button.is-recording,
    .chat-voice-button.is-recording .chat-voice-button__dot {
        animation: none;
        opacity: 1;
    }
}

/* ---------------------------------------------------------------------------
   Listing location, under the title

   Replaces the "Τοποθεσία" fieldset that used to sit far down the page beside a
   map. Location decides whether a listing is worth reading, so it belongs next
   to the title.
   --------------------------------------------------------------------------- */
.listing-header__location {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: -4px;      /* the h1 carries its own bottom margin */
    margin-bottom: 14px;
    font-size: 0.9375rem;
    line-height: 1.3;
    /* Muted deliberately: it sits directly under the title and should read as
       an attribute of it, not compete with it. */
    opacity: 0.75;
}

.listing-header__location svg {
    width: 16px;
    height: 16px;
    flex: 0 0 auto;
    color: var(--noiz-dark-orange, #ee6820);
}

@media (max-width: 767px) {
    .listing-header__location {
        margin-top: 2px;
        font-size: 0.875rem;
    }
}

/* ---------------------------------------------------------------------------
   Listing details: the right-hand panel follows the reader

   Title, fields and contact form travel together on the right while the photos
   and description scroll on the left - the arrangement Reverb uses, and it works
   for the same reason: on a listing with fifteen photos the way to ask about the
   item would otherwise be a long way from wherever you happen to be looking.
   --------------------------------------------------------------------------- */
/*
    .main-wrapper carries overflow: hidden, which silently disables sticky
    anywhere inside it: an ancestor with a clipping overflow becomes the
    containing scroll box, so the panel sticks to that instead of to the
    viewport and simply scrolls away. Everything on the panel itself was already
    correct - position, top, align-self - and it still did nothing, which is what
    made this hard to see.

    overflow-x: clip contains the same horizontal overflow without creating a
    scroll container, so sticky works again. Measured on the page rather than
    assumed: document scrollWidth stays at the viewport width either way, so
    nothing starts overflowing sideways.

    Scoped to the listing page via the body class rather than changed globally -
    the wrapper's clipping is doing a job everywhere else, and this is not the
    place to find out what.
*/
@media (min-width: 992px) {
    .view-details-page .main-wrapper {
        overflow: visible;
        overflow-x: clip;
    }
}

@media (min-width: 992px) {
    .listing-details-aside {
        position: sticky;

        /*
            Just enough air above the panel, and no more.

            This was 88px, written for a fixed header that this theme does not
            have - .page-header is static and scrolls away with everything else.
            The offset was therefore 88px of empty page above a pinned panel for
            the whole of the scroll, which is exactly the gap it looked like.
        */
        top: 16px;

        /*
            Room between the content and the panel's own edge.

            The column's 12px of Bootstrap gutter is the right amount when the
            panel is invisible, but once it pins it grows a shadow and reads as a
            surface - and text 12px from the edge of a surface looks cramped.
            Horizontal only: any padding at the top would put back the blank
            strip above the title that the margin below is careful to avoid.
        */
        /*
            No padding on the column itself.

            The card's inset moved to .listing-details-panel, so that anything
            outside that wrapper - the banner block - sits below the card at the
            column's own width instead of inside its padding.
        */
        padding-left: 0;
        padding-right: 0;

        /*
            Air above the title, inside the panel.

            This was zero on purpose once: padding here shows as blank space
            above the title for the whole time the panel is pinned, and at the
            time the panel had no visible edge, so that space read as a gap
            rather than as inset. Now that it grows a shadow and reads as a
            surface, text against its top edge is the thing that looks wrong.

            The margin below drops by the same 18px, so the title still lines up
            with the top of the photo in the resting state - which is what the
            margin is for.
        */

        /*
            Rounded, like the gallery frame beside it and the buttons inside it.

            Only meaningful once the panel is pinned and has a shadow to draw
            its edge - but set unconditionally rather than on .is-stuck, because
            a corner radius that appears the moment you scroll is a visible
            change of shape mid-scroll.
        */

        /*
            Without this the panel does not stick at all.

            .row is a flex container, so its children stretch to the full height
            of the row by default. A sticky element that is already as tall as
            its container has nowhere to travel, so it simply scrolls away with
            everything else - which is exactly what it did.

            flex-start lets the panel size to its own content and leaves the rest
            of the row's height as the range it can stick within.
        */
        align-self: flex-start;

        /*
            Line the title up with the top of the photo.

            Both columns start at the same y, but the gallery block sits 30px
            lower than the column it is in - a margin that collapses out of the
            inner <section> in the left column, where every element in the chain
            reports margin-top: 0.

            margin, not padding. Padding is inside the box, so it travelled with
            the panel when it stuck and left 30px of blank space above the title
            for the whole scroll. A margin does the same job in normal flow and
            disappears once the panel is pinned, which is where it is no longer
            aligning with anything.
        */
        margin-top: 12px;

        /*
            No max-height, and so no scrollbar of its own.

            Capping the height did guarantee the whole panel was reachable, but
            it put a second scrollbar on the page, which reads as a bug rather
            than a feature. Uncapped, a panel taller than the viewport scrolls
            with the page until its bottom arrives and sticks from there - the
            behaviour everyone already expects, and nothing to explain.
        */
    }
}

/* Below lg the two columns stack, and a pinned panel would cover the photos it
   is meant to describe. Static, in normal flow. */
@media (max-width: 991px) {
    .listing-details-aside {
        position: static;
        max-height: none;
        overflow: visible;
    }
}

/*
    A shadow once the panel is pinned, and none before.

    While the panel is scrolling with the page it is simply part of the page and
    needs no treatment. Once it stops and the photos keep moving underneath, a
    faint shadow explains why - it reads as one layer sitting above another
    rather than as content that has frozen.

    Kept very light on purpose. This is a hint about depth, not a card: anything
    heavier turns a quiet column of facts into a floating box competing with the
    photos.

    CSS cannot ask whether a sticky element is currently stuck, so the class is
    set from a sentinel - see listing_details.tpl.
*/
.listing-details-panel {
    transition: box-shadow 0.18s ease;
}

@media (min-width: 992px) {
    /* The class is set on the aside by the sentinel observer; the shadow is
       painted on the wrapper, which is the thing that looks like a card. */
    .listing-details-aside.is-stuck .listing-details-panel {
        /* Two layers: a tight one to draw the edge, a wide soft one for the
           lift. A single wide shadow at this strength turns into a grey haze
           with no discernible edge. */
        box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06), 0 10px 34px rgba(0, 0, 0, 0.14);
    }
}

@media (prefers-reduced-motion: reduce) {
    .listing-details-panel { transition: none; }
}

/* The tick in front of a delivery option is noise. Every other row states its
   value plainly, and with the unticked options hidden there is nothing left for
   a tick to distinguish it from. */
.listing-details-facts .value ul.checkboxes > li svg {
    display: none;
}

/* The title moved into this column, so it no longer needs the full-width
   two-column split it had as a page header. */
.listing-details-aside .listing-header {
    margin: 0 0 4px;
}

/*
    One left edge for the whole header.

    The row's negative gutter is off (margin: 0 above), so each column's own
    12px padding is no longer cancelled by it - the title and the location line
    have rules that zero their padding, but the condition tag and the price sat
    12px further in than both. Four items stacked vertically with two different
    left edges reads as a mistake, and the panel's padding now supplies all the
    inset any of them need.
*/
.listing-details-aside .listing-header > * {
    padding-left: 0;
    padding-right: 0;
}

/* The title is the loudest thing in the panel. It was competing with the price
   and the field labels at 1.6rem; at 2.15 it reads as the heading it is. */
.listing-details-aside .listing-header h1 {
    flex: 0 0 100%;
    max-width: 100%;
    font-size: 2.35rem;
    font-weight: 700;
    line-height: 1.14;
    margin-bottom: 10px;
}

@media (max-width: 1199px) {
    .listing-details-aside .listing-header h1 { font-size: 1.95rem; }
}

/* Condition, as a tag under the title - the first fact anyone checks on a
   second-hand instrument. Outlined rather than filled: it labels the item, it is
   not a button, and a solid block here would pull attention off the price. */
/*
    Condition and the specs button, one line.

    position: relative because the specs popover hangs off this row rather than
    off the button - anchored to the button it would be as narrow as the word
    "Χαρακτηριστικά", and the field list needs the panel's full width for its
    fixed 160px label column plus a value.
*/
.listing-header__tagline {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 14px;
    margin: 2px 0 10px;
}

.listing-header__condition {
    display: inline-block;
    margin: 0;
    padding: 4px 11px;
    border: 1px solid rgba(0, 0, 0, 0.18);
    border-radius: 999px;
    font-size: 0.8125rem;
    line-height: 1.3;
    white-space: nowrap;
}

/* Price. The largest text on the page after the title, since it is the other
   half of the decision. */
.listing-header__price {
    margin: 4px 0 16px;
    font-size: 2rem;
    font-weight: 700;
    line-height: 1.1;
}

.listing-header__price a {
    color: inherit;
    text-decoration: underline;
}

/* "From ..." and "/ month" are qualifiers, not part of the number. */
.listing-header__price-from,
.listing-header__price-unit {
    font-size: 0.9375rem;
    font-weight: 400;
    opacity: 0.7;
}

/* Similar listings, now full width below the listing rather than crammed into
   the panel. */
.listing-details-bottom {
    margin-top: 28px;
}

.listing-details-aside .listing-header > .col-md-2 {
    flex: 0 0 100%;
    max-width: 100%;
}

/* The field list, now a compact spec panel rather than a full-width table. */
.listing-details-facts {
    margin-bottom: 18px;
}

/*
    Label and value on one line, both left aligned, in one colour.

    They were pushed to opposite edges with space-between, the label greyed and
    the value right aligned. On a wide panel that left a gulf between "Μάρκα:"
    and "PRS" with the eye having to cross it, and the two halves of one fact
    looked like two different kinds of thing.

    A fixed label column instead: the values line up with each other, the label
    sits next to its value, and both read as the same sentence. No borders and
    tighter rows, so a short list of facts reads as a list rather than a table.
*/
.listing-details-facts .table-cell {
    display: flex;
    align-items: baseline;
    gap: 10px;
    padding: 3px 0;
}

/*
    The clearfix pseudo-elements have to go.

    Every row carries .clearfix, whose ::before is an empty box meant to contain
    floats. There are no floats here, but the row is a flex container, so that
    empty box becomes a real flex item - and the 10px gap then indents the label
    by 10px. Every field sat that far right of the title above it, which is
    visible now that the panel has an edge of its own.
*/
.listing-details-facts .table-cell::before,
.listing-details-facts .table-cell::after {
    display: none;
}

/*
    One label width for every row, written specifically enough to win.

    The theme sets .name to a fixed 160px, which beat a plain percentage here -
    so ordinary rows sat at 160px while the delivery row, which the theme rule
    does not reach, used 40% and started its value 69px further right. The values
    no longer lined up, which is the thing this panel is for.

    Fixed rather than a percentage, to match what the theme was already doing and
    so the column does not move as the panel width changes.
*/
.listing-details-facts .table-cell .name,
.listing-details-facts .table-cell.wide-field .name {
    flex: 0 0 160px;
    max-width: 160px;
    text-align: left;

    /*
        Readable, and still clearly the label.

        The theme paints .name #888, which on the white background is about
        3.5:1 - under the 4.5:1 minimum for body text, and it showed: the labels
        were noticeably harder to read than their own values.

        Derived from the text colour at 75% rather than hard-coded, so it lands
        correctly in the dark theme too, where a fixed grey would have to be
        light instead of dark. Opacity alone was not enough - the theme sets
        colour, and 100% opacity on #888 is still #888.
    */
    color: var(--body-font-color);
    font-weight: 600;
    opacity: 0.85;
}

/* The weight is on the label, as in the counters strip: the field names are
   what a reader scans, and bolding a dozen values made the whole list loud. */
.listing-details-facts .value {
    flex: 1 1 auto;
    text-align: left;
    font-weight: 400;
    overflow-wrap: anywhere;
}

/*
    The fieldset wrapper is stripped of its own styling here.

    fieldset_header.tpl has to stay - its opening divs are closed further down
    details.tpl, and removing it is what broke the layout earlier - but it draws
    a grey panel around whichever fields happen to be grouped. With the headings
    hidden, that produced a shaded block around three rows and nothing around the
    others, splitting one list of facts into two for no reason a reader could
    see.
*/
.listing-details-facts .fieldset,
.listing-details-facts .fieldset .body,
.listing-details-facts .fieldset .body > div {
    background: none;
    border: 0;
    padding: 0;
    margin: 0;
    box-shadow: none;
}

/*
    Checkbox fields line up with the rest.

    "Παράδοση" is a checkbox field, so field_out gives it the wide-field class
    and it was set to display: block - label on one line, ticked options on the
    next. Beside five aligned label/value rows it read as something having gone
    wrong rather than as a different kind of field.

    It uses the same two columns now. The options stack inside the value column
    when there is more than one, which keeps them tidy without breaking the
    alignment.
*/
/*
    flex-direction has to be forced back to row.

    The theme sets column on wide-field elsewhere, which is what kept the label
    stacked above its options no matter what else was set here - display was
    already flex and flex-wrap already nowrap, so nothing looked wrong until the
    computed flex-direction was read.
*/
.listing-details-facts .table-cell.wide-field {
    display: flex;
    flex-direction: row;
}

/* The utility margin on the options list pushes the value off the label's
   baseline; the row spacing is handled by the cell. */
.listing-details-facts .value ul.checkboxes.mt-2 {
    margin-top: 0;
}

/*
    The ticked options are a Bootstrap grid, and it has to be undone here.

    field_out renders them as <ul class="checkboxes row"> with each option a
    col-lg-4. That is three-across on a full-width page; inside a value column
    that is 60% of a third of the screen it gives each option a sliver, and
    "Στην χώρα μου" collapsed to an ellipsis.

    Stacked in the value column instead - one option per line, full width, tick
    beside its label.
*/
.listing-details-facts .value ul.checkboxes {
    display: flex;
    flex-direction: column;
    gap: 3px;
    margin: 0;
    padding: 0;
    list-style: none;
}

/*
    Only the options the seller actually chose.

    Flynax prints every option in the set and strikes through the ones that do
    not apply, so this listing showed "Στην χώρα μου", "Ευρώπη" and "Παγκόσμια"
    crossed out above the one true answer. That is a form control's way of
    thinking; on a listing the field should state its value the way every other
    row does. The chosen options carry .active.

    Scoped to this panel - the same markup elsewhere keeps its current
    behaviour.
*/
.listing-details-facts .value ul.checkboxes > li:not(.active) {
    display: none;
}

.listing-details-facts .value ul.checkboxes > li {
    display: flex;
    align-items: center;
    gap: 6px;
    flex: 0 0 auto;
    width: auto;
    max-width: 100%;
    padding: 0;
}

.listing-details-facts .value svg {
    flex: 0 0 auto;
}

/* ---------------------------------------------------------------------------
   Listing description, above the field list

   It used to print last, inside a fieldset below every field. It reads first
   now - after the photos, before the specifics - so it needs to look like prose
   rather than like another table row.
   --------------------------------------------------------------------------- */
.listing-description {
    margin: 0 0 22px;
    font-size: 1rem;
    line-height: 1.6;
    /* Long descriptions are often pasted as one unbroken block; honour any line
       breaks the seller actually typed. */
    white-space: pre-line;
    overflow-wrap: anywhere;
}

.listing-description .value {
    padding: 0;
}

/* Sellers paste links; keep them visible and stop a long URL widening the
   column on a phone. */
.listing-description a {
    color: var(--noiz-dark-orange, #ee6820);
    overflow-wrap: anywhere;
}

/* 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;

    /*
        The brand orange, and the same value in light.css and dark.css - so the
        bar looks identical in both themes. That was the point of the original
        dark surface: a notice built from theme variables is the shape of the
        old "Προβολή όλων" bug, correct in one theme and invisible in the other.
        A fixed brand colour keeps that property.

        Everything on it is white, by choice. Worth knowing the number if this
        is revisited: white on #ee6820 is 3.16:1, which clears the 3:1 that
        large text and non-text UI need but is under the 4.5:1 wanted for
        normal-size body text. The message is set larger and at 500 weight to
        buy back some of that; a darker orange would buy the rest, at the cost
        of no longer being the brand colour.
    */
    background: var(--noiz-dark-orange, #ee6820);

    /* Drives the icon too - the svg is fill="currentColor". */
    color: #ffffff;
    box-shadow: 0 -8px 28px -8px rgba(0, 0, 0, 0.35);

    /* 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 */

    /*
        17px, up from 15.2px, and a touch heavier.

        Both help here rather than being decoration: white on the brand orange
        measures 3.16:1, under the 4.5:1 that normal-size body text wants, and
        size and weight are the two things that make text at that ratio readable
        rather than merely legible.
    */
    font-size: 1.0625rem;
    font-weight: 500;
    line-height: 1.5;
    word-wrap: break-word;
}

/* Links were the brand orange, which is now the background - they would have
   vanished into it. White, underlined: on a single-colour bar the underline is
   the only thing left to mark a link, so it stays. */
.noiz-notice__text a {
    color: #ffffff;
    text-decoration: underline;
    text-underline-offset: 2px;
}

.noiz-notice__text a:hover {
    text-decoration-thickness: 2px;
}

/* 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;
    /* White, held slightly back so it reads as secondary to the message
       without becoming a hunt for it. */
    color: rgba(255, 255, 255, 0.85);
    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.18);
    color: #ffffff;
}

/* The focus ring was the brand orange, which is now the bar itself. */
.noiz-notice__close:focus-visible {
    outline: 2px solid #ffffff;
    outline-offset: 2px;
}

/* --- types ---------------------------------------------------------------
   No hairline, and no per-type colour.

   The bar used to carry a 3px rule along its top edge in a colour per type,
   with the icon tinted to match. Both are gone: everything on the orange is
   white now, so the type is carried by the ICON SHAPE alone - a cross in a
   circle, a triangle, a tick in a circle.

   That is not the loss it looks like. Shape was always the load-bearing signal
   here; it survives a monochrome screen and a red-green deficiency, which
   colour does not. The .noiz-notice--<type> classes still land on the element
   and still drive role and aria-live, so a screen reader announces an error as
   an alert exactly as before.

   The three colour rules are deleted rather than left in place because the icon
   is fill="currentColor" - a stale `color` here would quietly override the
   white and tint it back. */

.noiz-notice__text {
    color: #ffffff;
}

@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: 1rem;
    }
}

@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.
   ========================================================================== */

/*
    FIVE ACROSS ON BROWSE, NOT SIX.

    Six fitted, but at a 1440 window it left each card 227px wide and the
    photo 203px square - small for the one page whose whole job is letting
    somebody judge an instrument by looking at it. Five gives 272px and a
    248px photo, a fifth larger, for one fewer result per row.

    This deliberately departs from the note above, which brought browse to
    the home page's six-across so the same card would not read as two
    different grids. That still holds for everything the card IS - type,
    spacing, badges - but the two pages are doing different work: the home
    page scrolls a row sideways as a sampler, browse is a wall you scan.
    Scanning wants the bigger picture.

    Only >=1200px changes. The 992-1199 band stays at four, because five
    there would be ~190px cards - smaller than the six-across it replaced,
    which is the opposite of the point.
*/
@media (min-width: 1200px) {
    section#listings.grid > article.item {
        flex: 0 0 20%;
        max-width: 20%;
    }
}

@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;
}

/* ==========================================================================
   CHAT AUDIO PLAYER
   ==========================================================================
   Sits inside the message bubble. Built rather than using <audio controls>,
   which renders differently in every browser and is wider than the bubble at
   its narrowest in Chrome.

   Sized to the bubble, not the viewport: a voice note is a small object in a
   conversation, and a player that fills the width would read as the message
   rather than an attachment to it.
   ========================================================================== */

.chat-audio {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    max-width: 260px;
    padding: 8px 12px 8px 8px;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.06);
}

/*
    There is no li.me variant here any more, and there should not be one.

    The original pair of rules lightened the player on sent messages, on the
    stated grounds that "the bubble's own background is dark on sent messages".
    It is not. In the light theme a bubble has no background at all - style.css
    gives ul#messages_area > li a border and nothing else, and li.me only
    changes the border colour. So the inversion painted a white track and a
    white tint onto a white page, and a sent voice note arrived with an
    invisible progress bar.

    Sent versus received was the wrong axis. What actually changes the backdrop
    is the theme: dark.css sets #252525 on a received bubble and #2a2030 on a
    sent one. So the values below are dark-on-light for both bubble kinds, and
    dark.css carries the inversion for both.
*/

.chat-audio__el {
    display: none;                 /* ours is the visible one */
}

.chat-audio__toggle {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    border: 0;
    border-radius: 50%;
    background: var(--noiz-dark-orange, #ee6820);
    color: #fff;
    cursor: pointer;
}

.chat-audio__glyph {
    width: 16px;
    height: 16px;
}

/* Play and pause occupy the same slot; only one is ever shown, so the button
   does not change size when the state flips. */
.chat-audio__glyph.is-pause,
.chat-audio.is-playing .chat-audio__glyph.is-play {
    display: none;
}

.chat-audio.is-playing .chat-audio__glyph.is-pause {
    display: block;
}

/* 4px of pale grey was too faint to read as a control at all, particularly
   inside the tinted pill. Darker, and a little taller. */
.chat-audio__track {
    flex: 1 1 auto;
    position: relative;
    height: 5px;
    border-radius: 3px;
    background: rgba(0, 0, 0, 0.26);
    cursor: pointer;
}

/* A 4px bar is a hard target for a finger or a mouse. The padding is applied
   as a pseudo-element so the hit area grows without the bar getting thicker. */
.chat-audio__track::before {
    content: '';
    position: absolute;
    top: -10px;
    bottom: -10px;
    left: 0;
    right: 0;
}

.chat-audio__track:focus-visible {
    outline: 2px solid var(--noiz-dark-orange, #ee6820);
    outline-offset: 4px;
}

.chat-audio__fill {
    width: 0;
    height: 100%;
    border-radius: 3px;
    background: var(--noiz-dark-orange, #ee6820);
}

/* An explicit colour rather than opacity: 0.75. Opacity was applied over
   whatever the bubble's text colour happened to be, which on a pale bubble left
   the duration grey on near-white - the faintest thing in the player, and the
   one part carrying actual information. */
.chat-audio__time {
    flex: 0 0 auto;
    min-width: 38px;               /* holds "--:--" and "12:34" without shifting */
    font-size: 0.75rem;
    font-variant-numeric: tabular-nums;
    text-align: right;
    color: rgba(0, 0, 0, 0.62);
}

@media (prefers-reduced-motion: no-preference) {
    .chat-audio__fill {
        transition: width 0.1s linear;
    }
}

/* ==========================================================================
   CHAT COMPOSE: SEND BUTTON
   ==========================================================================
   The label sat off-centre. style.css gives every input[type=button] a fixed
   height: 40px, and div.send-controls then overrides the padding to 12px 24px.
   With border-box that leaves a 16px content box for roughly 19px of text, and
   the flex centring on the base rule does not reliably apply to the internal
   text of a replaced element like <input>, so the label drifted rather than
   being clipped.

   Letting the padding define the height removes the conflict: the box is as
   tall as its content plus padding, and the text is centred by construction
   instead of by a rule that inputs may ignore.
   ========================================================================== */

div.send-controls #send_message {
    height: auto;
    padding: 12px 24px;
    line-height: 1.2;
}

/* Own row, above the attachment controls, left aligned so it lines up with the
   attach button beneath it rather than sitting diagonally opposite it. */
.chat-compose-send {
    display: flex;
    width: 100%;
    justify-content: flex-start;
}

/* No mobile width rule here on purpose: style.css already makes this button
   full width under 768px, and a second rule at a different breakpoint would
   only be a place for the two to disagree later. */


/* ==========================================================================
   Listing page: actions, specs popover, facts strip
   ========================================================================== */

/*
    Three buttons, three weights.

    Filled, outlined, plain - contacting the seller is the thing most people
    came to do, making an offer is the alternative, saving is a bookmark. Three
    buttons shouting equally is the same as having no primary action, so the
    ranking is the whole point of the styling.

    Full width and stacked rather than side by side: the panel is a narrow
    column, and three Greek labels do not fit across it at a readable size.
*/
.listing-actions {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin: 20px 0 18px;
}

/*
    Written with the parent in the selector so it beats the theme's own button
    and anchor rules, which is what made the three disagree about their size.
*/
.listing-actions .listing-actions__btn {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    width: 100%;
    padding: 13px 18px;
    border: 1px solid transparent;
    border-radius: 8px;

    /*
        font-family: inherit is the whole reason two of these three looked
        different.

        <button> does not inherit the page font - browsers give it the system UI
        default - while <a> does. Contact and Make an offer are anchors and came
        out in Onest; Save to favourites is a button and came out in Arial, at a
        different size and with different letterforms, sitting directly beneath
        them.
    */
    font-family: inherit;
    font-size: 1rem;
    font-weight: 600;
    line-height: 1.2;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.listing-actions__btn:hover,
.listing-actions__btn:focus {
    text-decoration: none;
}

.listing-actions__btn svg {
    flex: 0 0 19px;
    width: 19px;
    height: 19px;
}

/*
    Written as a.<class>, not .<class>.

    Two of these three are anchors, and the theme's link colour is brand orange.
    A single class ties with `a` on specificity and loses on order, so the
    outlined button came out with orange text and the ranking the three weights
    exist to express collapsed. The tag qualifier is the smallest thing that
    wins.

    The label span inherits for the same reason - .link carries its own colour
    elsewhere in the theme.
*/
.listing-actions a.listing-actions__btn--primary {
    background: var(--button-color);
    color: var(--button-text-color);
}

.listing-actions a.listing-actions__btn--primary:hover,
.listing-actions a.listing-actions__btn--primary:focus {
    background: var(--button-hover-color);
    color: var(--button-text-color);
}

.listing-actions__btn .link {
    color: inherit;
}

/* Outlined, not filled in a second colour. Two solid blocks stacked read as two
   primary actions, and the border is enough to say "this is also a button". */
/*
    Both tag names, spelled out.

    The first version of this rule was `a.listing-actions__btn--secondary`,
    written to outrank the theme's link colour - which meant it never matched
    Save to favourites, a <button>. That button fell through to the theme's
    default black while Make an offer sat next to it in #111, and the two looked
    like different controls for no reason anyone could see.

    A tag qualifier is still needed to beat `a`, so both are listed rather than
    the qualifier dropped.
*/
.listing-actions a.listing-actions__btn--secondary,
.listing-actions button.listing-actions__btn--secondary {
    background: transparent;
    border-color: var(--highlight-border-color);
    color: var(--body-font-color);
}

.listing-actions a.listing-actions__btn--secondary:hover,
.listing-actions a.listing-actions__btn--secondary:focus,
.listing-actions button.listing-actions__btn--secondary:hover,
.listing-actions button.listing-actions__btn--secondary:focus {
    border-color: var(--noiz-dark-orange);
    color: var(--noiz-dark-orange);
}

/*
    There is no third weight any more.

    Save to favourites used to be a "ghost": no border and 75% opacity. Beside
    an outlined button in the same font at the same size, that did not read as a
    quieter variant - it read as the same button rendered in a slightly
    different grey, which looks like a bug rather than a hierarchy. Both
    secondary actions now share one treatment, and the primary is the only thing
    that stands apart.

    The rule is kept as a no-op comment rather than the class being left in the
    stylesheet unused: the class is gone from the markup too.
*/

/*
    Back into the column.

    style.css declares `.favorite { position: absolute }` - everywhere else on
    the site that class is a heart floating in the corner of a listing card, so
    absolute is right there and wrong here. Left alone it pulled the button out
    of the flex column and dropped it across the title.

    All four offsets are reset, not just position: they are set on the same rule
    and would otherwise sit there waiting for anything that gives this button a
    positioned ancestor.
*/
.listing-actions__btn.favorite {
    position: static;
    top: auto;
    right: auto;
    bottom: auto;
    left: auto;
    z-index: auto;
}

/*
    And no zoom on hover.

    style.css gives `.favorite:hover` a transform: scale(1.05) - a nice touch on
    the small heart floating over a grid card, and quite wrong on a full-width
    button, which grew sideways under the pointer while the button above it just
    changed colour. The two now hover identically: border and text to the
    accent, nothing moves.
*/
.listing-actions__btn.favorite:hover,
.listing-actions__btn.favorite:focus {
    transform: none;
}

/*
    Outline when not saved, filled when saved.

    The heart's fill/stroke have to be set in CSS, not left to the svg's own
    fill="none" stroke="currentColor" attributes: style.css targets .favorite svg
    with `fill: #bababa; stroke: none`, and any CSS declaration beats a
    presentation attribute. Unset, the heart was a solid grey blob in both
    states - which is the one thing this button must not be, since telling you
    which state you are in is its entire job.
*/
.listing-actions__btn.favorite svg {
    fill: none;
    stroke: currentColor;
}

/* Saved: the button takes the accent, border and all, so the state is legible
   without reading the label. */
.listing-actions__btn.favorite.remove {
    opacity: 1;
    color: var(--noiz-dark-orange);
    border-color: var(--noiz-dark-orange);
}

.listing-actions__btn.favorite.remove svg {
    fill: currentColor;
    stroke: currentColor;
}

/*
    The specs peek.

    A trigger and a panel that is filled by cloning the real list. Positioned
    against .listing-specs-peek, so the popover follows the button rather than
    the panel - the button can move without the popover needing a new offset.
*/
/* Static, so the popover resolves against .listing-header__tagline and gets the
   panel's full width rather than the button's. Inline-flex so it sits on the
   condition line instead of starting a row of its own. */
.listing-specs-peek {
    position: static;
    display: inline-flex;
    margin: 0;
}

/*
    Set to match the condition tag it now sits beside - same family, size and
    weight - so the two read as one line rather than as a tag with a heavier
    button stuck to it.

    font-family: inherit for the same reason as the action buttons: this is a
    <button>, and a button does not inherit the page font. It was rendering in
    Arial next to a span in Onest.
*/
.listing-specs-peek__trigger {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 0;
    background: none;
    border: 0;
    color: var(--body-font-color);
    font-family: inherit;
    font-size: 0.8125rem;
    font-weight: 300;
    line-height: 1.3;
    opacity: 0.75;
    cursor: pointer;
    transition: opacity 0.15s ease, color 0.15s ease;
}

.listing-specs-peek.is-open .listing-specs-peek__trigger,
.listing-specs-peek__trigger:hover,
.listing-specs-peek__trigger:focus {
    opacity: 1;
    color: var(--noiz-dark-orange);
}

.listing-specs-peek__trigger svg {
    flex: 0 0 15px;
    width: 15px;
    height: 15px;
}

/*
    A real surface, unlike the panel it sits in.

    The sticky panel is deliberately flat - it is part of the page. This is
    layered above the page and has to say so, or the field rows read as though
    they belong to whatever they happen to be covering.

    Pinned to both edges of the panel rather than given a width: the label
    column is a fixed 160px, and any width small enough to look like a tooltip
    left the values wrapping onto two lines.
*/
.listing-specs-peek__popover {
    position: absolute;
    top: calc(100% + 6px);
    left: 0;
    right: 0;
    z-index: 40;
    max-height: 60vh;
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 14px 18px;
    background: var(--body-background-color);
    border: 1px solid var(--highlight-border-color);
    border-radius: 10px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.13);
}

/*
    Listed / Views / Saves / Offers.

    Label left, number right - four rows read as a table that way, and the eye
    can run down the numbers without reading the labels twice. Quieter than the
    field list on purpose: this is context, not content.
*/
/*
    One line, not four rows.

    These are footnotes to the decision, not part of it - four full-width rows
    with the numbers pushed to the right edge gave them the weight of a spec
    table. Wrapped inline at a smaller size they read as a single caption under
    the buttons, which is what they are.
*/
.listing-facts-strip {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    /* Centred: four short pairs on one rule-topped line read as a caption for
       the block above them, and a caption sits under the middle of what it
       captions rather than hanging off its left edge. */
    justify-content: center;
    gap: 4px 18px;
    margin: 0 0 20px;
    /* No rule above it. The buttons already end the block they belong to, and a
       line between them and their own counters cut the panel in half where it
       did not need cutting - the size difference does that job on its own. */
    padding: 14px 0 2px;
    font-size: 0.8125rem;
}

.listing-facts-strip__row {
    display: inline-flex;
    align-items: baseline;
    gap: 5px;
}

/*
    The weight is on the label, not the number.

    These four pairs are read as a list of what is being reported - listed,
    views, offers, saves - and the labels are what a reader scans to find the
    one they want. Bolding the numbers instead made four unrelated figures the
    loudest thing in a strip that is deliberately quiet.
*/
.listing-facts-strip__label {
    font-weight: 600;
    opacity: 1;
}

.listing-facts-strip__value {
    font-weight: 400;
    opacity: 0.75;
}

/*
    The seller block's inline contact form is off.

    "Επικοινωνήστε με τον πωλητή" now opens the site's contact popup, and the
    same form sitting open underneath it made the button look decorative. The
    seller's identity - name, member since, reviews link - stays, because that is
    what a buyer is actually checking at this point.

    Hidden here rather than removed from listing_details_seller.tpl: that file's
    {if}/{else} branches open and close different numbers of divs, and editing it
    is how the whole left column disappeared once already.
*/
.listing-details-aside .seller-short > .form {
    display: none;
}


/*
    One left edge for the whole field list.

    Most of this site's fields belong to no group and render bare; the rest sit
    inside a fieldset, whose body has an unclassed inner div carrying 30px of
    padding meant to indent a group under its heading. The heading is hidden
    here, so that indent had nothing to indent from - the list simply stepped
    30px to the right halfway down and stepped back again.

    Scoped to .listing-details-facts so the fieldset keeps its indent on the
    submission form and everywhere else it is used as intended.

    #controller_area is in the selector to win, not to narrow. style.css sets
    the 30px through `#controller_area div.fieldset > div.body > div`, and an id
    beats any number of classes - three earlier attempts at this rule were in the
    stylesheet, matched the element, and lost silently. The id is on the page
    wrapper, so this changes nothing about which elements are selected.
*/
#controller_area .listing-details-facts .fieldset > .body > div {
    padding: 0;
}

/* The header is already d-none; this removes the space it reserved. */
#controller_area .listing-details-facts .fieldset > header {
    padding: 0;
}

/*
    One list, not a stack of one-row groups.

    Nearly every field on this site belongs to no group, and Flynax wraps each
    of those in its own div carrying margin-bottom: 20px. With one field per div
    that is 20px of air between every row - the fields read as a dozen separate
    blocks rather than as one list, and the eye cannot pair a label with its
    value across the gap.

    The rows carry their own 3px, raised to 5px here, which is the spacing this
    actually wanted.
*/
#controller_area .listing-details-facts .listing-fields > div {
    margin-bottom: 0;
}

.listing-details-facts .table-cell {
    padding: 5px 0;
}

/*
    The counters strip at the foot of the left column is off.

    "21 Προβολές" and "Αναρτήθηκε: πριν 4 μέρες" are now in the panel, in the
    facts strip, next to saves and offers - reading them twice on one page makes
    the page look assembled rather than designed.

    Only the two lists inside the section are hidden, not the section itself:
    the report-listing link is injected into it by a hook, and it is the one
    thing here that is not a duplicate.
*/
.view-details-page .listing-details-stat > ul.counters,
.view-details-page .listing-details-stat > ul.controls > li:first-child {
    display: none;
}

/*
    What is left of that section: the report link, alone under the panel.

    The section ships as a two-column flex row built for the full page width -
    counters left, controls right - and with one item left in it that layout
    only pushes the link off to one side. Reset to a centred block, at the size
    of a footnote, because that is what it is: findable, and never competing
    with the reasons to buy.
*/
/*
    Right, against the card's own inset, with air above it.

    justify-content rather than text-align, because the section carries
    Bootstrap's `d-flex` - `display: flex !important` - so a display change here
    is silently ignored and text-align has nothing to act on. align-items covers
    the column-reverse direction the section switches to below 576px, where
    justify-content works on the vertical axis instead.
*/
.listing-details-report .listing-details-stat {
    justify-content: flex-end;
    align-items: flex-end;
    margin: 30px 0 0;
    text-align: right;
}

.listing-details-report .listing-details-stat > ul.controls {
    margin: 0;
    padding: 0;
    list-style: none;
}

/* The theme pads these list items for a full-width stats row - 12px top and
   bottom, which is most of the 40px this 14px line was occupying and all of the
   gap under it. */
.listing-details-report .listing-details-stat > ul.controls > li {
    margin: 0;
    padding: 0;
}

/*
    Grey, not the brand orange.

    The plugin styles it as a .link, which takes the accent colour used for
    every "do this" control on the page. This is the opposite of those: a thing
    almost nobody needs, that should be findable without ever competing with the
    reasons to buy. Derived from the text colour so it lands correctly in the
    dark theme too.
*/
.listing-details-report .listing-details-stat #report-broken-listing,
.listing-details-report .listing-details-stat #report-broken-listing.link {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    color: var(--body-font-color);
    font-size: 0.8125rem;
    /* Tight line box: at the foot of the card, the font default left about 13px
       of slack under the text that read as extra padding. */
    line-height: 1.1;
    opacity: 0.55;
    cursor: pointer;
    transition: opacity 0.15s ease, color 0.15s ease;
}

.listing-details-report .listing-details-stat #report-broken-listing:hover {
    opacity: 1;
}

/* The plugin's own warning glyph, scaled down to match the text beside it -
   it ships at icon size for a full-width row - and taking the text's colour
   rather than keeping its own. */
.listing-details-report .listing-details-stat .rbl-icon {
    display: inline-flex;
    margin-left: 0 !important;
}

.listing-details-report .listing-details-stat .rbl-icon svg {
    width: 14px;
    height: 14px;
    fill: currentColor;
    stroke: currentColor;
}


/* ==========================================================================
   The offer form
   ========================================================================== */

.offer-form__asking {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 18px;
    padding-bottom: 12px;
    border-bottom: 1px solid var(--highlight-border-color);
    font-size: 0.9rem;
}

.offer-form__asking span {
    opacity: 0.6;
}

.offer-form__asking strong {
    font-size: 1.05rem;
}

.offer-form__label {
    display: block;
    margin-bottom: 6px;
    font-size: 0.875rem;
    font-weight: 600;
}

/*
    The euro sign is furniture, not content.

    It sits inside the field's own border rather than beside it, so the buyer is
    typing a number into something that already says what the number is. The
    input carries no border of its own - the wrapper is the field.
*/
.offer-form__amount {
    display: flex;
    align-items: center;
    margin-bottom: 18px;
    padding: 0 12px;
    border: 1px solid var(--form-field-line-color, var(--highlight-border-color));
    border-radius: 8px;
    background: var(--body-background-color);
}

.offer-form__amount:focus-within {
    border-color: var(--noiz-dark-orange);
}

.offer-form__currency {
    flex: 0 0 auto;
    padding-right: 8px;
    font-size: 1.25rem;
    font-weight: 600;
    opacity: 0.55;
}

.offer-form__amount input {
    flex: 1 1 auto;
    width: 100%;
    padding: 12px 0;
    border: 0;
    background: transparent;
    font-size: 1.25rem;
    font-weight: 600;
}

.offer-form__amount input:focus {
    outline: none;
    box-shadow: none;
}

.offer-form textarea {
    width: 100%;
    margin-bottom: 18px;
    resize: vertical;
}

.offer-form__submit {
    width: 100%;
    padding: 13px 18px;
    border: 0;
    border-radius: 8px;
    background: var(--button-color);
    color: var(--button-text-color);
    font-size: 0.9875rem;
    font-weight: 600;
    cursor: pointer;
    transition: background-color 0.15s ease;
}

.offer-form__submit:hover:not(:disabled) {
    background: var(--button-hover-color);
}

.offer-form__submit:disabled {
    opacity: 0.6;
    cursor: default;
}


/* ==========================================================================
   The Offers page
   ========================================================================== */

.offers-page__group {
    margin-bottom: 36px;
}

.offers-page__heading {
    margin: 0 0 14px;
    font-size: 1.25rem;
    font-weight: 700;
}

/*
    An offer is a fact and a decision side by side.

    Left: what it is about and what was said. Right: the number, its state, and
    the buttons. The number is the largest thing in the row because it is what
    the row is - scanning a list of offers means scanning a column of prices.
*/
.offer-row {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    justify-content: space-between;
    gap: 20px;
    margin-bottom: 12px;
    padding: 18px 20px;
    border: 1px solid var(--highlight-border-color);
    border-radius: 10px;
}

/* Resolved offers step back. They are history, and history should not compete
   with the one row that still needs an answer. */
.offer-row--declined,
.offer-row--withdrawn,
.offer-row--countered,
.offer-row--expired {
    opacity: 0.6;
}

.offer-row--accepted {
    border-color: var(--noiz-dark-orange);
}

.offer-row__main {
    flex: 1 1 300px;
    min-width: 0;
}

.offer-row__listing {
    margin-bottom: 4px;
    font-size: 1.05rem;
    font-weight: 600;
}

.offer-row__meta {
    font-size: 0.85rem;
    opacity: 0.65;
}

.offer-row__date::before {
    content: '·';
    margin: 0 6px;
}

.offer-row__message {
    margin-top: 10px;
    padding-left: 12px;
    border-left: 2px solid var(--highlight-border-color);
    font-size: 0.9rem;
}

.offer-row__side {
    flex: 0 0 auto;
    text-align: right;
}

.offer-row__amount {
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1.1;
}

.offer-row__status {
    margin-top: 2px;
    font-size: 0.85rem;
    opacity: 0.7;
}

.offer-row__status--accepted {
    color: var(--noiz-dark-orange);
    opacity: 1;
    font-weight: 600;
}

.offer-row__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 8px;
    margin-top: 12px;
}

.offer-row__actions button {
    padding: 8px 14px;
    border: 1px solid var(--highlight-border-color);
    border-radius: 6px;
    background: transparent;
    color: inherit;
    font-size: 0.875rem;
    font-weight: 600;
    cursor: pointer;
    transition: background-color 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}

.offer-row__actions button:disabled {
    opacity: 0.5;
    cursor: default;
}

/* Accept is the affirmative action and reads as the primary one; decline and
   counter stay outlined so the row has one obvious answer rather than three. */
.offer-row__action--accept {
    background: var(--button-color);
    border-color: var(--button-color);
    color: var(--button-text-color);
}

.offer-row__action--accept:hover:not(:disabled) {
    background: var(--button-hover-color);
    border-color: var(--button-hover-color);
}

.offer-row__actions button:not(.offer-row__action--accept):hover:not(:disabled) {
    border-color: var(--noiz-dark-orange);
    color: var(--noiz-dark-orange);
}

@media (max-width: 575px) {
    .offer-row__side {
        flex: 1 1 100%;
        text-align: left;
    }

    .offer-row__actions {
        justify-content: flex-start;
    }
}

/* "Your offer" - which of the rows in a chain the reader wrote. Quiet: it is a
   clarification, not a heading. */
.offer-row__mine {
    margin-left: 8px;
    padding: 1px 7px;
    border: 1px solid var(--highlight-border-color);
    border-radius: 999px;
    font-size: 0.75rem;
}


/* ==========================================================================
   Listing page: breathing room, description accordion, breadcrumbs
   ========================================================================== */

/*
    Air between the photos and the panel.

    The two columns are adjacent, so the only thing separating them was the
    gallery's own 12px of column padding - and now that the panel grows a shadow
    when it pins, 12px reads as the two touching. Added on the photo side rather
    than as panel padding: padding inside the panel moves its text but not its
    edge, so the gap would not have changed at all.
*/
@media (min-width: 992px) {
    .view-details-page #content {
        padding-right: 44px;
    }
}

/*
    The description, as a disclosure.

    <details>/<summary> rather than a div and a click handler: the state, the
    keyboard behaviour and the accessible name come from the browser, and it
    works before any script has run.

    The default triangle marker is removed in favour of a chevron that can be
    rotated, because the native one cannot be positioned or coloured and sits
    tight against the text.
*/
.listing-description {
    margin-bottom: 26px;
}

.listing-description__summary {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 0;
    border-bottom: 1px solid var(--highlight-border-color);
    font-size: 1.15rem;
    font-weight: 700;
    cursor: pointer;
    list-style: none;
    user-select: none;
}

/* Both are needed: -webkit-details-marker for Safari, ::marker for the rest. */
.listing-description__summary::-webkit-details-marker {
    display: none;
}

.listing-description__summary::marker {
    content: '';
}

.listing-description__summary::after {
    content: '';
    width: 9px;
    height: 9px;
    margin-left: auto;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    /* Pointing down when open, right when closed. The -3px lifts the glyph onto
       the text's optical centre - a rotated square hangs low otherwise. */
    transform: translateY(-3px) rotate(45deg);
    transition: transform 0.15s ease;
    opacity: 0.55;
}

.listing-description:not([open]) .listing-description__summary::after {
    transform: translateY(0) rotate(-45deg);
}

.listing-description__summary:hover {
    color: var(--noiz-dark-orange);
}

/*
    Line breaks once, not twice.

    The theme renders this field with `white-space: pre-line`, and the value has
    already been through nl2br - so every newline the seller typed arrives as
    "<br>\n" and is honoured twice: once as the tag, once as the preserved
    newline. Every description on the site was double-spaced, and the blank
    lines between paragraphs were four lines deep.

    It also put most of a screen of blank above the first word, because the
    partial that renders the value opens with an HTML comment followed by two
    newlines - which `pre-line` faithfully reproduced.

    `normal` is correct precisely because the <br>s are already there: they do
    the work, and whitespace goes back to collapsing the way it does everywhere
    else on the page.
*/
.listing-description .value {
    padding-top: 16px;
    white-space: normal;
}

/*
    Breadcrumbs, legibly.

    13px is a size for something you are not meant to read. On a marketplace the
    trail is how a buyer gets from one instrument to the rest of its category,
    so it is navigation rather than decoration and should be readable at a
    glance.

    Set on the descendants as well as the container: the theme sizes the li and
    the a directly, so a rule on #bread_crumbs alone changes only the separators.
*/
#bread_crumbs,
#bread_crumbs li,
#bread_crumbs li a,
#bread_crumbs ul {
    font-size: 0.9375rem;
    line-height: 1.5;
}

/*
    And dark enough to read.

    The links were #888 - about 3.5:1 on white, under the 4.5:1 minimum, and the
    same mistake the field labels had. Derived from the text colour rather than
    hard-coded so the dark theme gets a light grey instead of a dark one; the
    separators stay lighter, since they are punctuation rather than words.
*/
#bread_crumbs li a {
    color: var(--body-font-color);
    opacity: 0.8;
}

#bread_crumbs li a:hover {
    color: var(--noiz-dark-orange);
    opacity: 1;
}


/*
    Both disclosures read as section headings.

    The summary was set at 1.15rem, which put it between the field labels and
    the title without belonging to either. At 1.45rem it is unambiguously a
    heading for the block under it - which is what it has to be, since on a
    closed one it is the only thing there is.

    The specs accordion borrows the description's summary class rather than
    getting a parallel set of rules: two disclosures on one page that open the
    same way should not be able to drift apart visually.
*/
.listing-description__summary {
    font-size: 1.6rem;
}

/* Closed by default, so it needs a little air above it - the description
   directly above has none of its own once collapsed. */
.listing-specs-acc {
    margin-bottom: 26px;
}

.listing-specs-acc > .listing-details-facts {
    padding-top: 14px;
}


/* ==========================================================================
   Forum discussions
   ========================================================================== */

/*
    A list of threads, not a list of links.

    Each row is one hit area covering the title and the reply count, because the
    count is part of what you are deciding on - "84 replies" is the difference
    between a discussion and an unanswered question - and a link that stops
    short of it makes the number look like decoration.

    Rules on the item rather than the link so the separator spans the row at
    full width; :last-child loses it so the block does not end on a line that
    divides it from nothing.
*/
/*
    The "?" beside the heading, and the bubble it opens.

    A standing paragraph of explanation competed with the results every time the
    accordion opened, while only ever being read once. Behind an icon it is
    there for whoever wants it.

    Sized off the heading with em, not rem: the summary is 1.6rem and a fixed
    18px circle beside it looks like a mistake. This tracks whatever the heading
    is set to.

    relative here so the bubble positions against the icon; the summary itself
    is left alone, since giving a <summary> a position would put it in front of
    its own marker.
*/
.listing-forum-threads__help {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /*
        flex-shrink off. The summary is a flex container, which makes this a
        flex item - and a round icon that has been squeezed into an ellipse
        because the heading beside it wanted the room is worse than no icon.
        Measured at 5.1x9.6 before this line went in.
    */
    flex: 0 0 auto;
    width: 1.5em;
    height: 1.5em;
    margin-left: 0.5em;
    /* Nudged up to sit against the cap height rather than the baseline - beside
       a 1.6rem heading a centred circle reads as having fallen. */
    vertical-align: 0.15em;
    border-radius: 50%;
    /*
        Solid, and inverted against the page rather than hard-coded black.

        The ask was a black circle with a white "?", which is what these two
        tokens give in the light theme. Naming them instead of #000/#fff means
        the dark theme gets the same idea rather than the same hex - a pure
        black disc on a near-black background would disappear, so there it
        flips to a light disc with a dark "?" and still reads as one mark.
    */
    background: var(--body-font-color);
    color: var(--body-background-color);
    /*
        Sized against the mark, not the heading: the box is 1.5em of the "?"
        rather than a fraction of the 1.6rem summary, so the glyph fills the
        disc at any heading size - the outlined version was set the other way
        round and read as a large ring with a small character adrift in it.

        In rem, so it lands at 15px beside a 25.6px heading - a little smaller
        than the 18px ring it replaces, which was the ask. The first attempt
        put this at 0.52rem and, with the box measured in em OF THAT, produced
        a 9.6px dot: half the size again rather than "a bit smaller".
    */
    font-size: 0.625rem;
    font-weight: 600;
    line-height: 1;
    opacity: 0.75;
    cursor: help;
    transition: opacity 0.15s ease, background-color 0.15s ease;
}

.listing-forum-threads__help:hover,
.listing-forum-threads__help:focus-visible {
    opacity: 1;
    background: var(--noiz-dark-orange);
    color: #fff;
    outline: none;
}

/*
    The bubble.

    visibility rather than display, so it can transition and so a screen reader
    still finds the text aria-describedby points at.

    Set at a fixed 300px and in ordinary body type: it is a sentence, and
    inheriting the heading's 1.6rem would produce a paragraph in display type.
    Anchored left:0 against the icon and allowed to run right, which keeps it
    inside the content column - the icon sits just after a short heading, so
    there is always room that way.

    Surface matched to .listing-specs-peek__popover: same border, radius and
    shadow. Two floating layers on one page that disagree about what a floating
    layer looks like is worse than either choice.
*/
.listing-forum-threads__bubble {
    position: absolute;
    top: calc(100% + 9px);
    left: 0;
    z-index: 40;
    width: 300px;
    padding: 11px 14px;
    background: var(--body-background-color);
    border: 1px solid var(--highlight-border-color);
    border-radius: 10px;
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.13);
    color: var(--body-font-color);
    font-size: 0.875rem;
    font-weight: 300;
    line-height: 1.55;
    text-align: left;
    white-space: normal;
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.15s ease, visibility 0.15s ease;
}

.listing-forum-threads__help:hover .listing-forum-threads__bubble,
.listing-forum-threads__help:focus-visible .listing-forum-threads__bubble {
    opacity: 1;
    visibility: visible;
}

/*
    Touch has no hover, and the icon cannot be tapped for it either - the tap
    lands on the summary and toggles the accordion. Rather than leave a control
    that does nothing, the icon is hidden below the tablet breakpoint; the
    results speak for themselves and the heading already names them.
*/
@media (max-width: 767px) {
    .listing-forum-threads__help {
        display: none;
    }
}

/*
    Two columns, eight results.

    Four results in one column read as a short list; eight in one column read as
    a wall, and push the seller's card off the screen. Two columns keep the
    whole block about the height it already was while doubling what it holds.

    Grid rather than CSS columns: `column-count` would let a result break across
    the column boundary, splitting an excerpt from the byline that says who
    wrote it. Grid keeps each result whole.

    One column below 640px, where two would leave roughly twenty characters a
    line for Greek prose.
*/
.listing-forum-threads__list {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0 32px;
    margin: 14px 0 0;
    padding: 0;
    list-style: none;
}

@media (min-width: 640px) {
    .listing-forum-threads__list {
        grid-template-columns: 1fr 1fr;
    }
}

/*
    Every item keeps its rule, including the last.

    In one column the last rule separated the results from nothing, so it was
    removed. In a grid "last" is a position in the flow, not a position on the
    screen: with an odd count the final item sits alone in the left column and
    hiding its rule leaves one row half-underlined. Keeping them all is
    count-agnostic, and the closing rule now divides the results from the
    "see more" link rather than from nothing.
*/
/*
    min-width: 0, or one column eats the other.

    A grid item defaults to min-width: auto, which means it refuses to become
    narrower than its own content. Forum posts contain URLs like

        thomann.de/gr/search_dir.html?sid=0070707e5870fb4e91cd9957d7510aac&xsid=…

    which is one unbreakable word roughly 90 characters long. The 1fr track
    stretched to fit it and the other column collapsed to a ribbon four
    characters wide - the thread titles beside it were wrapping one word per
    line. min-width: 0 lets the track hold its share and hands the problem to
    the wrapping rules below.
*/
.listing-forum-threads__item {
    min-width: 0;
    border-bottom: 1px solid var(--highlight-border-color);
}

.listing-forum-threads__link {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    padding: 11px 0;
    color: var(--body-font-color);
}

.listing-forum-threads__link:hover .listing-forum-threads__title {
    color: var(--noiz-dark-orange);
}

/*
    Thread titles are written by people, not by a form, and run long -
    "Θα αγοράζατε ποτέ μία κιθάρα της δεκαετίας 80 ή 90 με τιμή 1000+ ευρώ;" is
    a real one. Wrapping is correct; what must not happen is the reply count
    being pushed off the row, hence the flex-shrink pairing below.
*/
.listing-forum-threads__title {
    flex: 1 1 auto;
    /* Same reason as the grid item: a flex item will not shrink below its
       content either, and thread titles carry model numbers with no spaces. */
    min-width: 0;
    overflow-wrap: anywhere;
    line-height: 1.45;
}

.listing-forum-threads__meta {
    flex: 0 0 auto;
    font-size: 0.875rem;
    color: var(--body-font-color);
    opacity: 0.65;
    white-space: nowrap;
}

/*
    The matching reply, under the thread it belongs to.

    Indented and quieter than the title: the title is the thing being chosen
    between, the quote is the evidence for choosing it. Set at the same size as
    the reply count rather than body size, so four of these read as a list and
    not as four paragraphs.
*/
.listing-forum-threads__post {
    padding: 0 0 11px;
    font-size: 0.875rem;
    line-height: 1.5;
}

/*
    anywhere, not break-word.

    break-word only breaks a word that would overflow ON ITS OWN LINE, so it
    does not help the intrinsic-width calculation that sized the column in the
    first place - the track still asks for the whole URL. `anywhere` counts
    toward min-content, which is what lets two equal columns survive a post
    containing a session-id query string.
*/
.listing-forum-threads__quote {
    display: block;
    overflow-wrap: anywhere;
    color: var(--body-font-color);
    opacity: 0.75;
}

/*
    The matched phrase, marked the way a search result marks it.

    Background rather than bold: the excerpt is already dimmed, and bolding
    inside dimmed text reads as damage. Explicit colours because the browser
    default for <mark> is black-on-yellow, which is unreadable in dark mode and
    ignores the theme in light.
*/
.listing-forum-threads__quote mark {
    padding: 0 2px;
    border-radius: 2px;
    /* Declared twice on purpose: the first is the fallback for anything without
       color-mix(), the second derives the tint from the brand colour so it
       tracks the theme instead of being a second hard-coded orange. */
    background: rgba(240, 138, 36, 0.22);
    background: color-mix(in srgb, var(--noiz-dark-orange) 22%, transparent);
    color: inherit;
}

.listing-forum-threads__byline {
    display: block;
    margin-top: 5px;
    color: var(--body-font-color);
    opacity: 0.55;
}

/*
    The way out, set apart from the threads above it.

    Reads as a link rather than a button: it leaves the listing, and anything
    button-shaped this far down the page competes with "Στείλτε μήνυμα" in the
    panel, which is the one action this page is actually for.
*/
.listing-forum-threads__more {
    display: inline-block;
    margin-top: 14px;
    font-size: 0.9375rem;
    color: var(--noiz-dark-orange);
}

.listing-forum-threads__more:hover {
    text-decoration: underline;
}


/* ==========================================================================
   The seller card at the foot of the panel
   ========================================================================== */

/*
    A rule, not a box.

    The theme paints every .side_block with the grey content background, which
    made the seller a card inside a card - and the panel already has an edge of
    its own once it pins. A hairline separates it from the counters above
    without adding a second surface.

    The selector carries .listing-details-aside to outrank
    `#content_wrapper .side_block` and friends in style.css; a lone class rule
    was ignored.
*/
.listing-details-aside .seller-card,
.seller-card {
    margin-top: 4px;
    padding: 18px 0 0;
    border-top: 1px solid var(--highlight-border-color);
    border-radius: 0;
    background: none;
    box-shadow: none;
}

.seller-card__head {
    display: flex;
    align-items: center;
    gap: 12px;
}

/* Fixed and round. A photo of any aspect ratio is cropped to the same circle,
   so a column of sellers lines up instead of stepping in and out. */
.seller-card__avatar {
    flex: 0 0 54px;
    width: 54px;
    height: 54px;
    border-radius: 50%;
    overflow: hidden;
}

.seller-card__avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* The fallback: one letter on a flat tint. Not a stock silhouette - the same
   grey person on every listing tells a reader nothing. */
.seller-card__avatar--letter {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--content-background-color);
    color: var(--body-font-color);
    font-size: 1.25rem;
    font-weight: 700;
    text-transform: uppercase;
    opacity: 0.85;
}

/*
    Name and rating share the first line; the location takes the second.

    A wrapping flex row rather than fixed positions, because the middle item is
    injected by the seller-reviews plugin and is simply absent for a seller with
    no reviews - where a two-column layout would leave a hole.

    The location is pushed onto its own line by flex-basis rather than by being
    outside the list, so the thumbnail sits to the left of all three lines
    instead of only the first two.
*/
.seller-card__identity {
    display: flex;
    flex-wrap: wrap;
    /*
        Baseline. Twice now the alternative has been tried and it is wrong both
        times, for the same reason each time.

        Within a line box, the baseline sits at half-leading plus the font's
        ascent - so a bigger font's baseline is lower in the box even when the
        boxes are identical. Centring the boxes therefore drops the 17px name
        below the 13.6px text beside it, and forcing a shared line-height does
        not help: it makes the boxes equal while leaving the ascents different,
        which is exactly what puts the name low.

        Baseline alignment is the one rule that ignores size, which is what this
        line needs - it has three text sizes on it. The stars were never part of
        this problem; see .srr-star below.
    */
    align-items: baseline;
    column-gap: 10px;
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
    padding: 0;
    list-style: none;
}

.seller-card__identity > .seller-card__location {
    flex: 0 0 100%;
}

/* No shared line-height. It was written to support centring the boxes, and
   equal boxes with unequal ascents is precisely what pushed the name below the
   rest - see the note on align-items above. */

.seller-card__name {
    font-size: 1.0625rem;
    font-weight: 700;
    line-height: 1.25;
}

.seller-card__name a {
    color: inherit;
}

.seller-card__name a:hover {
    color: var(--noiz-dark-orange);
}

/*
    The rating row, which the seller-reviews plugin injects.

    It ships as an <li class="account-rating counter"> built for a wider box and
    carries the theme's counter spacing; here it needs to sit tight under the
    name at the size of a caption.
*/
.seller-card__identity .account-rating {
    gap: 6px;
    margin: 0;
    padding: 0;
    font-size: 0.85rem;
}

.seller-card__identity .srr-stars {
    margin-left: 0 !important;
    margin-right: 4px !important;
}

/*
    The stars, sized to the text beside them.

    This is what actually looked wrong on this line, and it is a size problem
    rather than a position one - which is why three attempts at aligning it
    failed. The plugin draws each star in a 16px box for a rating widget that
    stands on its own; here they sit next to 13.6px text, so they overshot the
    caps at the top and the baseline at the bottom and read as floating above
    the line no matter where the box was aligned.

    13px matches the text's own extent. background-size: contain is required
    with it - the image is drawn at its natural size otherwise and would simply
    be cropped by the smaller box.
*/
.seller-card__identity .srr-star {
    width: 13px;
    height: 13px;
    background-size: contain;
    background-repeat: no-repeat;
    background-position: center;
}

.seller-card__identity .srr-account-rating {
    font-weight: 700;
}

/* Tight under the name: the two lines are one block about one person, and the
   3px of air was enough to read as two separate facts. The line-height on the
   row above supplies all the separation needed. */
.seller-card__location {
    display: flex;
    align-items: center;
    gap: 7px;
    margin-top: -2px;
    font-size: 0.9rem;
    opacity: 0.75;
}

.seller-card__location svg {
    flex: 0 0 16px;
    width: 16px;
    height: 16px;
}

.seller-card__listings {
    display: inline-block;
    margin-top: 14px;
}


/*
    The similar-listings row, sized like every other row scroller.

    style.css has a rule for listing cards that live inside an <aside>:

      body:not(.no-sidebar) aside:not(.two-middle) section:not(.side_block) .featured > li
      @media screen and (min-width: 1440px) { flex: 0 0 25%; max-width: 25% }

    This row is in the bottom blocks area, which content.tpl renders inside an
    <aside>, so it matched - and at (0,4,3) it beats the shared component's own
    (0,3,0) rule. The cards came out four across at 335px instead of six at
    206px, which is exactly the mismatch with the homepage this change set out
    to remove.

    #main_container is in the selector purely to outrank that: it wraps the
    whole page, so it narrows nothing. Scoped to .row-scroller__viewport rather
    than applied to .featured generally, so ordinary aside grids elsewhere keep
    the theme's four-across behaviour.
*/
#main_container .row-scroller__viewport > ul.featured > li {
    flex: 0 0 auto;
    width: calc((100% - 100px) / 6);
    max-width: none;
    min-width: 170px;
}

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

@media (max-width: 767px) {
    #main_container .row-scroller__viewport > ul.featured > li {
        width: 44%;
        min-width: 0;
    }
}


/*
    "Παρόμοιες καταχωρίσεις" reads like the homepage rows it copies.

    style.css sizes those headings through `body.home-page section.content_block
    > h3` - scoped to the homepage, so this row inherited the default 18.7px at
    weight 400 while the rows it is modelled on are 2.15em at 600. Same values
    here rather than widening the theme's selector, which would restyle every
    block on every page.

    The top margin is the other half of it: on the homepage these rows have the
    one above them for separation, and here it follows the seller card with
    nothing between.
*/
section.content_block.similarListings {
    margin-top: 54px;
}

section.content_block.similarListings > h3 {
    font-size: 2.15em;
    font-weight: 600;
    margin-bottom: 22px;
}

/*
    Full-width thumbnails, as on the homepage.

    featured.tpl gives each card Bootstrap column classes, and their 12px of
    horizontal padding took 24px out of a 207px card - so the artwork rendered
    at 183px square against the homepage's 207px, which is exactly the "smaller
    thumbnails" difference. The homepage boxes already come out at zero padding;
    the gap between cards is the flex `gap`, not column padding, so removing it
    costs nothing.
*/
#main_container .row-scroller__viewport > ul.featured > li {
    padding-left: 0;
    padding-right: 0;
}


/*
    The delivery row sat 8px low.

    Its value is a <ul class="checkboxes row mt-2"> rather than plain text, and
    .mt-2 is a Bootstrap utility - which means `margin-top: 0.5rem !important`.
    An earlier rule here tried to zero it and lost silently to that flag, so the
    value hung below its own label while every other row lined up, and the row
    was 44px tall against everyone else's 36.

    !important to match, which is the only thing that beats a utility class, and
    scoped tightly enough that it cannot affect .mt-2 anywhere else.
*/
.listing-details-facts .value ul.checkboxes.mt-2 {
    margin-top: 0 !important;
}

/*
    A rule and more air above "Παρόμοιες καταχωρίσεις".

    It is a different kind of thing from everything above it - the page has
    finished talking about this instrument and started suggesting others - and
    at 54px it still read as one more section of the listing. The line makes the
    break explicit rather than relying on the reader to feel it.
*/
section.content_block.similarListings {
    margin-top: 90px;
    padding-top: 46px;
    border-top: 1px solid var(--highlight-border-color);
}


/* ==========================================================================
   The listing panel on mobile
   --------------------------------------------------------------------------
   Below lg the theme moves the panel's children into an `aside.left.second-copy`
   it builds in the content column (flynaxTpl.sidebar in js/lib.js). That copy
   is not .listing-details-aside, so none of the panel rules above reach it -
   which is why the title bled off both edges and the buttons sat on the screen
   edge. These are the few that have to apply there too.
   ========================================================================== */

@media (max-width: 991px) {
    /* The copy is dropped in with no padding of its own, so its contents ran
       edge to edge. */
    aside.left.second-copy {
        padding-left: 16px;
        padding-right: 16px;
    }

    /*
        The same inset for the description, the specs and the price history.

        #content has 12px of column padding and the row cancels it with a -12px
        gutter, so its contents start at x=0 - the accordion titles and every
        line of description text were touching the screen edge.

        Applied to .content-section rather than to .listing-details, so the
        gallery above keeps running full width. A photo bleeding to the edges is
        right on a phone; a paragraph doing it is not. 16px matches the panel
        copy above, so the description lines up with the title.
    */
    .view-details-page .content-section {
        padding-left: 16px;
        padding-right: 16px;
    }

    /*
        The title was cut off at both ends, and the cause was not overflow.

        .listing-header is a Bootstrap .row, whose -12px gutter is normally
        cancelled by the column padding inside it. The desktop rule that zeroes
        that margin is scoped to .listing-details-aside and does not match the
        copy, so the row hung 12px past each edge of a full-width container and
        the first and last letters were clipped.
    */
    aside.left.second-copy .listing-header {
        margin-left: 0;
        margin-right: 0;
    }

    aside.left.second-copy .listing-header > * {
        padding-left: 0;
        padding-right: 0;
    }

    /* 27px was the theme's default, inherited for the same reason. Sized to the
       column it is now in. */
    aside.left.second-copy .listing-header h1 {
        font-size: 1.6rem;
        line-height: 1.2;
        margin-bottom: 8px;
    }

    /*
        The counters on one line.

        With all four labels this needs about 427px at 11px, so it wrapped on
        every phone made - and the size that would actually fit four pairs into
        343px is around 9px, which nobody can read.

        Dropping one label is what makes it fit: "πριν 1 εβδομάδα" reads as a
        date without being told it is one, where the other three are bare
        numbers and cannot lose theirs. That gets it onto one line from 390px
        up, which is most phones in use; a 375px screen - an SE or a mini -
        still takes two.
    */
    .listing-facts-strip {
        font-size: 0.6875rem;
        column-gap: 12px;
        row-gap: 2px;
    }

    .listing-facts-strip__row--listed .listing-facts-strip__label {
        display: none;
    }
}


/* ==========================================================================
   The panel's card surface
   --------------------------------------------------------------------------
   Everything that makes the panel look like a card lives here rather than on
   the <aside>. The aside stays the sticky grid column; this wrapper is the
   visible surface, so anything the template leaves outside it - the banner
   block - reads as sitting below the card while still travelling with it.
   ========================================================================== */

@media (min-width: 992px) {
    .listing-details-panel {
        /* 12px at the foot rather than 22: the report link is the last thing in
           the card now that the banner has left it, and it was floating in the
           middle of the bottom inset. */
        padding: 18px 26px 12px;
        border-radius: 14px;
    }
}

/* The side blocks, now a row of their own after the columns. */
.listing-details-side-blocks {
    margin-top: 26px;
}

@media (max-width: 991px) {
    /* The mobile copy already carries the 16px inset; a second one here would
       indent the card inside it. */
    .listing-details-panel {
        padding: 0;
    }
}


/* ==========================================================================
   Multi-value fields, and the specs popover at a size that fits
   ========================================================================== */

/*
    Several values on one line, separated by a bullet.

    Fields like Παράδοση hold a set - "Στην χώρα μου", "Χέρι με χέρι" - and the
    theme renders them as a grid of Bootstrap columns, so each one took a line
    of its own and the row grew as tall as the number of options. Stacked with
    no separator they also read as two unrelated rows rather than as one answer
    with two parts.

    Inline with a bullet between says "these belong together" in the width of a
    character. The selector is `.active ~ .active`, not `+`: the unticked
    options are display:none but still siblings, so adjacency would skip the
    separator whenever a hidden one sat between two shown ones.
*/
.listing-details-facts .value ul.checkboxes {
    display: block;
    margin: 0;
}

.listing-details-facts .value ul.checkboxes > li.active {
    display: inline;
    width: auto;
    max-width: none;
    padding: 0;
}

.listing-details-facts .value ul.checkboxes > li.active ~ li.active::before {
    content: '•';
    margin: 0 7px;
    opacity: 0.4;
}

/*
    The popover, sized to hold a full field list.

    At the page's 16px a twelve-row listing came to 491px and ran off the bottom
    of the window. Smaller type here is not a compromise - a hover panel is
    glanced at, not read - and it is the difference between the whole list
    fitting and half of it needing a scroll.

    The label column shrinks with it: 160px is sized for the wider list in the
    left column, and it was pushing the values further right than they needed to
    be in a narrower box.
*/
.listing-specs-peek__popover.listing-details-facts .table-cell {
    padding: 2px 0;
    font-size: 0.875rem;
}

/*
    min-width as well as flex-basis, or only half the rows narrow.

    style.css sets `min-width: 160px` on .name above 768px, and a min-width
    beats a flex-basis - but only for the rows it targets, which is
    :not(.wide-field). So the ordinary rows kept a 160px label column while the
    checkbox rows took the 138px asked for here, and their values started 22px
    apart in a list that is meant to be one column.
*/
.listing-specs-peek__popover.listing-details-facts .table-cell .name,
.listing-specs-peek__popover.listing-details-facts .table-cell.wide-field .name {
    flex: 0 0 138px;
    min-width: 138px;
    max-width: 138px;
}


/*
    "Ιστορικό τιμής" as a disclosure like the two above it.

    The block renders its own <h3> - Header is a column on the block row, and
    Smarty 2 cannot pass blocks_manager a modified copy of the array - so the
    heading is hidden here and the <summary> carries the title instead. Hiding
    rather than editing the block keeps the name coming from
    blocks+name+price_history, editable in the admin like every other block.
*/
.listing-price-history .content_block > h3 {
    display: none;
}

/* The block ships as a full-width bottom block with its own outer spacing; in
   the content column that reads as a gap between the title and its chart. */
.listing-price-history .content_block {
    margin: 0;
    padding: 0;
    background: none;
}

.listing-price-history > .content_block,
.listing-price-history .price-history-wrapper {
    padding-top: 14px;
}


/* ==========================================================================
   A reduced price
   ========================================================================== */


/*
    One line, above the price, on the listing page and on every card:

        €1,083.21  9% μείωση τιμής        <- struck, grey, small / red, small
        €992.87                           <- the price, untouched

    Both halves are deliberately small and the live price is deliberately left
    alone. An earlier version put the struck figure after the price and turned
    the price green, which made the number a buyer actually pays the one styled
    as an alert, and two prices sharing a line read as a range rather than as a
    before and after.

    The element is a flex row so the two halves stay on one line and share one
    gap wherever it appears - inside li.system (itself `d-flex flex-wrap`),
    inside li.price_tag, and inside the listing header. flex-basis: 100% is what
    makes it take a row of its own inside those flex parents; on the listing
    page the header is not a flex container, so width: 100% carries it there.
*/
.price-drop-line {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    column-gap: 8px;
    flex: 0 0 100%;
    width: 100%;
    margin-bottom: 2px;
    font-size: 0.875rem;            /* 14px - a caption, not a second price */
    font-weight: 400;
    line-height: 1.3;
}

.price-drop-line__was {
    color: var(--price-was);
    /* The default line-through sits mid-glyph on these numerals and can be
       mistaken for a hyphen at small sizes; a thinner rule reads as struck
       rather than as punctuation. */
    text-decoration-thickness: 1px;
    text-underline-offset: 0;
    white-space: nowrap;
}

.price-drop-line__pct {
    color: var(--price-drop);
    white-space: nowrap;
}

/*
    The listing page shows it a little larger, in step with the 2rem price it
    sits above - 14px under a figure that size reads as a footnote someone
    forgot to remove.
*/
.listing-header__price .price-drop-line {
    font-size: 1rem;
    margin-bottom: 4px;
}

/*
    List view keeps the price in its own narrow column, so the two halves stack
    there rather than being clipped.
*/
section#listings.list .list-view-price .price-drop-line {
    margin-bottom: 3px;
}

/* ==========================================================================
   Photo reordering on the add/edit listing step
   ==========================================================================
   The dragging itself is jQuery UI sortable and predates this file; what was
   missing was any sign that it existed. Until the R2 URL fix on 2026-08-12 the
   thumbnails on that page were broken, so there was not even an image to grab.

   Lives here rather than in controllers/add_listing/add_listing.css because
   that file is compiled from a .sass source we have no build step for, and
   editing the CSS alone would leave the two disagreeing.
   ========================================================================== */

.upload-files__hint {
    margin: 0 0 12px;
    font-size: 0.875rem;
    color: var(--price-was, #6B6B6B);
}

/* Doubles as the save confirmation - see orderSaveNotice(). The colour is the
   only thing that changes, so the line does not move and nothing reflows under
   the grid while someone is dragging in it. */
.upload-files__hint.is-saved {
    color: var(--price-drop, #D93025);
    font-weight: 500;
}

/*
    "Main photo", on whichever tile is currently first.

    :first-child rather than a class the JS maintains, so it follows the drag
    live - jQuery UI moves the element, and the badge is simply already on the
    one that ends up first. Nothing to keep in sync and nothing to re-render.

    Only while there is more than one photo (.is-reorderable): with a single
    image it states the obvious.
*/
.picture-cont__main-badge {
    display: none;
}

.upload-files.is-reorderable > .picture-cont:first-child .picture-cont__main-badge {
    position: absolute;
    top: 8px;
    left: 8px;
    z-index: 2;
    display: block;
    padding: 3px 8px;
    border-radius: 4px;
    background: rgba(0, 0, 0, 0.72);
    color: #fff;
    font-size: 0.75rem;
    font-weight: 500;
    line-height: 1.4;
    pointer-events: none;   /* never in the way of the drag handle underneath */
}

/*
    The positioning context for the badge, and NOTHING else.

    This rule also carried `display: block`, which broke every thumbnail on the
    page. file-upload.css makes this wrapper a flex column:

        .upload-files > div > span { display: flex; flex-direction: column; }
        .upload-files > div span.item { width: 100%; padding-bottom: 66%; }

    and span.item gets its box from being blockified as a flex item. Forcing the
    wrapper back to `block` left span.item inline, where width and padding-bottom
    buy nothing, so the tile collapsed to zero height and the image inside it -
    absolutely positioned at height: 100% - rendered at nothing. The file loaded
    every time; there was simply no box to draw it in.

    Worth remembering how it got through: the check was naturalWidth > 0, which
    only proves the bytes arrived. It says nothing about whether the thing is on
    screen. Measure geometry.
*/
.upload-files > .picture-cont > span {
    position: relative;
}

/* ==========================================================================
   Header: Σύνδεση/Εγγραφή
   ==========================================================================
   Replaces the anonymous person glyph a logged-out visitor used to see beside
   "Νέα καταχώριση". Same action, now with a name on it.

   Secondary on purpose. "Νέα καταχώριση" is the filled brand-orange call to
   action and should stay the loudest thing in the header; two solid buttons
   side by side would make a visitor choose between them instead of reading
   one. An outline carries equal weight structurally and less weight visually.

   .btn supplies the shared shape - 40px, 8px radius, the Onest stack - so only
   the colours and the border are set here. Worth knowing: .btn styles
   `a.button, .btn`, and this is a <button>, which does NOT inherit the page
   font the way an <a> does. The font-family in .btn is what saves it; if that
   rule ever loses its font, this lands in the browser's default sans.
   ========================================================================== */

/*
    THEMED WITH VARIABLES, NOT WITH A DARK SELECTOR. Read this before adding a
    colour anywhere in this file.

    This button was invisible on the dark theme - black text on the near-black
    header - and both halves of that were my mistake.

    First, `color: var(--noiz-black)`. That reads like "the text colour" and is
    not: --noiz-black is a BRAND colour, #010101 in light.css AND in dark.css.
    It does not flip. The variable that flips is --body-font-color, #111111
    against #DADADA.

    Second, the correction I had written for it could never have run. This
    theme has no dark class and no dark attribute anywhere on the document:
    lib.js switches themes by ENABLING AND DISABLING the light.css and dark.css
    <link> elements, and it sets data-theme on the #theme-switcher button
    itself - not on <html>, not on <body>. So `:root[data-theme="dark"]` and
    `body.dark-theme` match nothing, ever. (The theme's own style.css has three
    [data-theme="dark"] rules for .scam_notice with the same problem.)

    Which means there is exactly one correct way to theme anything here: use
    the custom properties that light.css and dark.css both define. They are
    swapped wholesale with the stylesheet, so a rule written in terms of them
    is right in both themes and needs no second rule at all.

        --body-font-color         #111111  /  #DADADA
        --highlight-border-color  #d4d4d4  /  #4D4D4D
        --cat-link-color          #777777  /  #989898   (muted text)

    The hover tints stay as literal rgba on purpose: at 5% they read as "very
    slightly lighter or darker than whatever is behind me", which is the same
    intent in both themes, and both are visible because the underlying colours
    differ.
*/
.header-auth-btn {
    background: transparent;
    color: var(--body-font-color, #111);
    border: 1px solid var(--highlight-border-color, #d4d4d4);
    font-size: 0.9375rem;
    font-weight: 500;
    white-space: nowrap;   /* "Σύνδεση/Εγγραφή" must not break across two lines */
    transition: background-color 0.15s ease, border-color 0.15s ease;
}

.header-auth-btn:hover {
    background: rgba(127, 127, 127, 0.14);
    border-color: var(--body-font-color, #111);
}

.header-auth-btn:focus-visible {
    outline: 2px solid var(--noiz-dark-orange, #ee6820);
    outline-offset: 2px;
}

/* Below md the header gets tight and "Νέα καταχώριση" is hidden entirely
   (d-none d-md-flex on it), so this becomes the only control there - it can
   afford to shed some padding rather than push the search field. */
@media (max-width: 767px) {
    .header-auth-btn {
        padding: 0 12px;
        font-size: 0.875rem;
    }
}

/* ==========================================================================
   Header: the signed-in avatar
   ==========================================================================
   Replaces the generic person glyph in the header trigger with the account's
   own photo, or a coloured initial when there is none.

   Sized here rather than in the shared block, the same way .udm-avatar sizes
   the 48px one inside the dropdown: avatar_with_initials.tpl deliberately
   emits no dimensions of its own, so each place it appears decides.
   ========================================================================== */

.header-avatar {
    display: block;
    flex: 0 0 auto;
    line-height: 0;   /* the img is inline-level; without this the span keeps descender space */
}

.header-avatar .avatar-image,
.header-avatar .avatar-initials {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    object-fit: cover;      /* a non-square upload crops rather than distorts */
    font-size: 0.8125rem;   /* the initial, scaled for 32px rather than the menu's 48px */
}

/*
    A hairline so a light photo does not bleed into a light header.

    inset rather than a border: a border would add to the 32px and push the
    row taller, and this sits on top of the image instead.
*/
.header-avatar .avatar-image {
    /* Themed variable, not a black tint - see the note on .header-auth-btn.
       At 8% black this hairline simply vanished against the dark header. */
    box-shadow: inset 0 0 0 1px var(--highlight-border-color, #d4d4d4);
}


/* ==========================================================================
   Seller reviews - the two-column layout from Martin's design
   ========================================================================== */

/*
    Summary card left, reviews right.

    The old layout stacked score, then a full-width star histogram, then the
    list - so the reviews themselves started below the fold while the summary
    got a whole band of the page for five short bars.

    Grid rather than float: the summary is a fixed 300px because it holds five
    bars whose length is meaningful, and a column that reflows changes what the
    bars appear to say. The list takes what is left.

    One column below 860px, where 300px of card leaves the reviews too narrow
    to read.
*/
.srr-reviews__layout {
    display: grid;
    grid-template-columns: 1fr;
    gap: 24px;
    margin-top: 18px;
}

@media (min-width: 860px) {
    .srr-reviews__layout {
        grid-template-columns: 300px 1fr;
        align-items: start;
    }
}

.srr-reviews__bar {
    gap: 12px;
    padding-bottom: 14px;
    border-bottom: 1px solid var(--highlight-border-color);
}

.srr-reviews__heading {
    margin: 0;
    font-size: 1.4rem;
}

/* The count reads as part of the heading, not as a separate label. */
.srr-reviews__count {
    margin-left: 8px;
    opacity: 0.55;
    font-weight: 400;
}

/*
    A card, unlike the list beside it.

    The reviews are the page; this is a summary of them, and the border is what
    stops the two columns reading as one long run of text.
*/
.srr-summary {
    padding: 18px;
    border: 1px solid var(--highlight-border-color);
    border-radius: 12px;
}

.srr-summary__score {
    padding-bottom: 14px;
    border-bottom: 1px solid var(--highlight-border-color);
    margin-bottom: 14px;
}

.srr-summary__value {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 6px 0 4px;
    font-size: 2rem;
    font-weight: 700;
    line-height: 1.1;
}

.srr-summary__based {
    font-size: 0.875rem;
    opacity: 0.65;
}

/*
    The distribution.

    Rows are links - each one filters the list, which the old markup did and
    which is easy to lose in a redesign. min-width: 0 on the track so a long
    bar cannot push the count off the row.
*/
.srr-bar {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 3px 0;
    color: var(--body-font-color);
}

.srr-bar:hover .srr-bar__fill {
    background: var(--noiz-dark-orange);
}

.srr-bar__label {
    flex: 0 0 10px;
    font-size: 0.875rem;
    opacity: 0.7;
}

.srr-bar__track {
    position: relative;
    flex: 1 1 auto;
    min-width: 0;
    height: 6px;
    border-radius: 3px;
    background: var(--highlight-border-color);
    overflow: hidden;
}

.srr-bar__fill {
    display: block;
    height: 100%;
    border-radius: 3px;
    background: #f5a623;
    transition: background-color 0.15s ease;
}

.srr-bar__count {
    flex: 0 0 auto;
    min-width: 34px;
    text-align: right;
    font-size: 0.8125rem;
    opacity: 0.6;
}

/* ---------------------------------------------------------------- the list */

.srr-list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.srr-review {
    padding: 18px 0;
    border-bottom: 1px solid var(--highlight-border-color);
}

.srr-review:first-child {
    padding-top: 0;
}

.srr-review:last-child {
    border-bottom: none;
}

/*
    Avatar and identity on one line, everything else below it.

    The old markup split a single review across two rows - name/date, then
    title/stars - which read as two separate items when several were stacked.
*/
.srr-review__head {
    display: flex;
    align-items: center;
    gap: 12px;
}

.srr-review__avatar {
    flex: 0 0 auto;
}

.srr-review__avatar .avatar-image,
.srr-review__avatar .avatar-initials {
    width: 42px;
    height: 42px;
    border-radius: 50%;
    object-fit: cover;
}

/* The initials fallback needs to centre its letter itself. */
.srr-review__avatar .avatar-initials {
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--highlight-border-color);
    font-weight: 600;
}

.srr-review__who {
    min-width: 0;
}

.srr-review__name {
    font-weight: 600;
    overflow-wrap: anywhere;
}

.srr-review__meta {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    margin-top: 2px;
}

.srr-review__age {
    font-size: 0.8125rem;
    opacity: 0.6;
    cursor: default;
}

.srr-review__title {
    margin-top: 10px;
    font-weight: 600;
}

.srr-review__text {
    margin-top: 6px;
    line-height: 1.55;
    overflow-wrap: anywhere;
}

/*
    The seller's answer, indented under the review it answers.

    A rule down the left rather than a filled box: it is the same conversation,
    one step in, and a second background colour in a list of reviews reads as a
    different kind of object entirely.
*/
.srr-review__reply {
    margin: 12px 0 0 18px;
    padding: 10px 0 2px 14px;
    border-left: 2px solid var(--highlight-border-color);
}

.srr-review__reply-head {
    display: flex;
    align-items: baseline;
    gap: 10px;
    margin-bottom: 4px;
    font-weight: 600;
    font-size: 0.9375rem;
}

.srr-review__reply-text {
    line-height: 1.55;
    opacity: 0.85;
    overflow-wrap: anywhere;
}


/* ==========================================================================
   Mobile: keep the right-hand controls off the screen edge
   ========================================================================== */

/*
    The signed-in avatar was reaching, and on Alex's phone overflowing, the
    right edge - clipped so only its left half showed.

    Two things do it together. The column carries Bootstrap's `pr-0`, so it has
    no right padding of its own and sits flush against the container's content
    edge; and it is a flex item that was free to shrink below its content, so
    the 32px avatar overflowed the 30px box it had been given and hung out to
    the right. Measured at 375px: container right 45, avatar right 67.

    flex-shrink: 0 stops the box being squeezed under its content, and the
    padding restores a gutter that `pr-0` removed. Both are scoped to the
    header so nothing else inherits them.
*/
/*
    THE AVATAR WAS HANGING OFF THE RIGHT EDGE ON PHONES, and the reason is one
    line of the theme's own mobile block - style.css, inside
    @media screen and (max-width: 767px):

        .user-navbar .circle .default > span { width: 0; text-indent: -1000px; }

    That was written for the old markup, where .default > span was the signed-in
    person's NAME: on a phone there is no room for it, so it was collapsed to
    nothing and shoved a thousand pixels off-screen. The avatar wrapper I added
    is a span in exactly that slot, so it inherits a fate meant for a word.

    Measured at 375px before this rule:

        .header-avatar    width 0    right 360
        .avatar-initials  width 32   right 392    <- 17px past the screen edge

    The wrapper collapses; the avatar inside it is display:flex, so unlike a run
    of text it ignores the text-indent and simply draws from its parent's edge
    outwards. Which is the clipped half-circle in Alex's screenshot.

    So this has to be scoped to the same breakpoint and win on specificity -
    four classes against three. text-indent goes back to 0 as well, because it
    inherits, and a photo avatar (an <img>, inline-level) WOULD be dragged off
    by it even though the initials disc is not.

    Sized here for all three so the number cannot drift between the wrapper and
    what it wraps.
*/
/*
    ONE NUMBER, DECLARED ONCE PER BREAKPOINT.

    The size used to be written out in two places - here and in the mobile rule
    below that exists to beat style.css's `width: 0; text-indent: -1000px`. That
    held while both said 32px, and broke the moment one of them changed: the
    avatar went to 46px for the taller header row, the mobile wrapper stayed at
    32, and a 46px disc drawn out of a 32px box hung 14px past the right edge of
    the screen. Exactly the bug this block was written to fix, reintroduced from
    the other side.

    A custom property removes the coupling: the wrapper, the photo, the initials
    disc and the mobile override all read the same value, so there is nothing
    left to keep in step by hand.
*/
.user-navbar {
    --header-avatar: 40px;
}

.header-avatar,
.header-avatar .avatar-image,
.header-avatar .avatar-initials {
    width: var(--header-avatar, 40px);
    height: var(--header-avatar, 40px);
}

@media screen and (max-width: 767px) {
    .user-navbar {
        --header-avatar: 34px;
    }

    /* Still needed, and still four classes deep, to beat the theme's own rule -
       but the number now comes from the same place as everything else. */
    .user-navbar .circle.logged-in > .default > .header-avatar {
        width: var(--header-avatar, 34px);
        text-indent: 0;
    }
}

/*
    And the last 10px, so the circle lines up with everything else rather than
    merely sitting inside the page.

    .circle > .default carries 10px of horizontal padding as its click target.
    On the right that padding is the difference between the avatar stopping at
    350 and the 360 the category button, the search box and the breadcrumb all
    use. Dropped on this trigger only; the target keeps its full 44px height
    and its left padding.
*/
.user-navbar .circle.logged-in > .default {
    padding-right: 0;
}

/*
    The notice bar's close button, same complaint.

    Its -6px right margin is an optical trick: it pulls the button's padding
    box outward so the glyph lines up with the text above it rather than the
    invisible edge of its hit area. That is right on a wide screen and wrong on
    a phone, where the bar's own gutter is all that stands between the X and
    the edge of the display - and 24px of padding minus 6px of margin leaves
    18px, which is where the thumb of the person holding the phone already is.

    The pull is dropped below the tablet breakpoint. The button keeps its full
    30px hit area either way; only the optical nudge goes.
*/
@media (max-width: 767px) {
    .noiz-notice__close {
        margin-right: 0;
    }

    .noiz-notice__inner {
        padding-left: 18px;
        padding-right: 18px;
    }
}


/* ==========================================================================
   "Απαντά συνήθως μέσα σε λίγα λεπτά" - the reply-time badge
   ========================================================================== */

/*
    Sits directly under the name on a profile.

    Deliberately quiet: grey text at 0.875em with a hairline clock, not a
    coloured pill. It is a fact about the seller, in the same register as their
    location - and a badge loud enough to look like a promotion invites the
    reader to discount it. The star rating next to it is the thing that should
    carry colour.

    Negative top margin because the theme gives h1 a 1.5rem bottom margin, which
    is the right gap before a block of content and much too big between a name
    and the line describing it. Pulling it up rather than changing the h1 keeps
    this contained to profiles.
*/
/*
    flex, not inline-flex, and this is load-bearing rather than taste.

    An inline-flex box is an atomic inline-level box: its vertical margins are
    applied but never collapse with a sibling's. The h1 above carries a 30px
    bottom margin, so with inline-flex the negative top margin here did nothing
    at all and the badge sat a full 30px below the name - measured, not assumed.
    As a block-level flex box the two margins collapse to 30 - 22 = 8, which is
    the gap a subtitle wants.

    width: fit-content keeps the box only as wide as the text, so the title
    attribute's tooltip and any future hover target do not span the column.
*/
.reply-time {
    display: flex;
    width: fit-content;
    align-items: center;
    gap: 6px;
    margin: -22px 0 20px;
    font-size: 0.875em;
    /* The theme's own muted-text colour, which flips with the stylesheet
       (#777777 / #989898). A hardcoded grey needs a dark-theme rule, and on
       this theme a dark-theme rule cannot work - see .header-auth-btn. */
    color: var(--cat-link-color, #6b6b6b);
}

.reply-time__icon {
    width: 15px;
    height: 15px;
    flex: 0 0 auto;   /* the flex row must not squeeze the clock oval */
    opacity: 0.8;
}




/* ==========================================================================
   The "why we need your number" line on the SMS verification step
   ========================================================================== */

/*
    Sits above the code box on both verification steps - registration and
    add-listing.

    Quiet, not alarming. A red or yellow box would read as a warning about the
    user, when the message is the opposite: an explanation of what WE are doing
    and why. Grey text at the body size, with a left rule to mark it as an aside
    rather than an instruction.

    Themed with variables only - --cat-link-color and --highlight-border-color
    both flip with the stylesheet. This template has no dark class and no dark
    attribute, so a :root[data-theme="dark"] rule here would be dead code; see
    the note on .header-auth-btn.
*/
.sms-activation-step-why {
    max-width: 46em;              /* long lines are the enemy of a read-once explanation */
    margin: 0 0 1.25rem;
    padding-left: 12px;
    border-left: 3px solid var(--highlight-border-color, #d4d4d4);
    font-size: 0.9375em;
    line-height: 1.5;
    color: var(--cat-link-color, #777);
}


/* ==========================================================================
   SMS verification step - "verify later" is an escape hatch, not the action
   ========================================================================== */

/*
    The skip button was the biggest, blackest thing on the page: it inherited the
    theme's filled primary style, so the visual hierarchy said "the thing to do
    here is skip", when the thing to do is enter the code.

    Specificity matters here and is easy to get wrong. The theme styles
    `input[type="submit"]` - an element plus an attribute, (0,1,1) - so a bare
    class at (0,1,0) LOSES and the button stays black. Qualifying with the
    element and attribute puts this at (0,2,1).

    Only applied while the button means "later": the same element becomes the
    real "next step" once verification succeeds, and that one should be
    prominent. The template adds this class conditionally for exactly that
    reason.

    Themed with variables, since dark-theme selectors do not work in this
    template - see the note on .header-auth-btn.
*/
/*
    "Πίσω" and "verify later" are THE SAME CONTROL, visually.

    They are different elements - one is the theme's <a>, the other an
    <input type="submit"> that has to stay an input because it submits the form
    and carries confirm_late - so the only way to guarantee they match is to
    declare them together. Two rules that merely look equivalent drift the
    moment one is edited.

    The values are the theme's own link style, lifted from style.css:247
    (a:link, a:visited, .link): --link-color, no underline, 1em. Nothing bespoke,
    so if the site's link colour changes these follow it, in both themes -
    --link-color is one of the variables that flips.
*/
.sms-activation-step .form-buttons a:not(.button),
.sms-activation-step .form-buttons input[type="submit"].sms-activation-step-skip {
    background: transparent;
    border: 0;
    padding: 0;
    height: auto;
    line-height: 1.4;
    font-family: inherit;
    font-size: 1em;
    font-weight: 400;
    color: var(--link-color);
    text-decoration: none;
    box-shadow: none;
    cursor: pointer;
}

.sms-activation-step .form-buttons a:not(.button):hover,
.sms-activation-step .form-buttons input[type="submit"].sms-activation-step-skip:hover {
    background: transparent;
    color: var(--link-color-hover);
    text-decoration: underline;
    box-shadow: none;
}

/*
    The receipt line, now sitting under the field it refers to. Smaller and
    quieter than the explanation above the form: one is context you read before
    acting, the other is confirmation you glance at afterwards.
*/
.sms-activation-step-message {
    margin-top: 1rem;
    font-size: 0.9375em;
    color: var(--cat-link-color, #777);
}


/* ==========================================================================
   SMS verification step - one job per screen
   ========================================================================== */

/*
    A centred card with a single instruction, digit boxes, and everything else
    demoted. Replaces a page whose most prominent control was "skip".

    All colour comes from the theme variables, which are the only thing that
    flips between light and dark in this template - see .header-auth-btn.
*/
.sms-verify {
    max-width: 460px;
    /* Left, not centred - Alex's call. The card keeps its width; it just starts
       where the rest of the page's content starts instead of floating in the
       middle of an empty column. */
    margin: 0;
    padding: 2rem;
    text-align: center;
    background: var(--surface-2, transparent);
    border: 1px solid var(--highlight-border-color, #d4d4d4);
    border-radius: 12px;
}

.sms-verify__icon {
    display: block;
    color: var(--cat-link-color, #777);
    line-height: 0;
    margin-bottom: 12px;
}

.sms-verify__icon svg { display: inline-block; }

.sms-verify__title {
    margin: 0 0 6px;
    font-size: 1.25rem;
    font-weight: 500;
}

.sms-verify__sent {
    margin: 0 0 1.5rem;
    font-size: 0.9375em;
    color: var(--cat-link-color, #777);
}

/* --------------------------------------------------------- the digit boxes */

.sms-verify__boxes {
    display: flex;
    justify-content: center;
    gap: 8px;
    margin-bottom: 1rem;
}

/*
    Sized for a thumb, not a mouse: 52x60 keeps the tap target well over the
    44px minimum, and the 1.5rem digit is readable while glancing between the
    SMS and the screen.

    text-align + a wide box is what makes this read as "one digit here" without
    any other affordance.
*/
.sms-verify__box {
    width: 52px !important;
    height: 60px;
    padding: 0;
    text-align: center;
    font-size: 1.5rem;
    font-weight: 500;
    border: 1px solid var(--highlight-border-color, #d4d4d4);
    border-radius: 8px;
    background: var(--body-background-color, #fff);
    color: var(--body-font-color, #111);
}

.sms-verify__box:focus {
    outline: none;
    border-color: var(--noiz-dark-orange, #ee6820);
    box-shadow: 0 0 0 3px rgba(238, 104, 32, 0.18);
}

/*
    The confirm button stays for anyone who pastes and reaches for a button, but
    the boxes auto-submit on the last digit so most people never use it.
*/
.sms-verify__submit {
    min-width: 160px;
}

/* ------------------------------------------------------- resend, and the why */

.sms-verify__resend {
    margin: 1rem 0 0;
    font-size: 0.875em;
    color: var(--cat-link-color, #777);
}

/*
    Still an <input> because flModal binds to input[name=new_code] and sets its
    .val(). Only the appearance is a link.
*/
input.sms-verify__resend-btn {
    background: transparent !important;
    border: 0;
    padding: 0 0 0 4px;
    height: auto;
    color: var(--link-color, #ee6820);
    font-size: 1em;
    text-decoration: underline;
    box-shadow: none !important;
}

input.sms-verify__resend-btn:hover {
    background: transparent !important;
    color: var(--link-color-hover, #FF8200);
}

/*
    "Wrong number?" sits with the resend, not with the footnote.

    Same size and colour as the resend line above it, so the two read as one
    pair of ways out rather than a new section. Tighter top margin because they
    belong together.
*/
.sms-verify__fix {
    margin: 0.35rem 0 0;
    font-size: 0.875em;
    color: var(--cat-link-color, #777);
}

.sms-verify__fix a {
    padding-left: 4px;
    color: var(--link-color, #ee6820);
    text-decoration: underline;
}

.sms-verify__fix a:hover {
    color: var(--link-color-hover, #FF8200);
}

/*
    Alex's padding, and centred to match the rest of the card.

    30px inside a card that already carries 32px puts the text well clear of the
    edge - which is the point, it is a footnote and should read as one. The rule
    above it stays inside the padding rather than spanning the card: a divider
    that overhangs its own border was the last thing wrong with this block.
*/
.sms-verify__why {
    margin: 1.75rem 0 0;
    padding: 30px;
    border-top: 1px solid var(--highlight-border-color, #d4d4d4);
    font-size: 0.8125em;
    line-height: 1.65;
    color: var(--cat-link-color, #777);
    text-align: center;
}

/*
    "Πίσω" and "verify later" belong together, under the card.

    They were a left-floating link and a right-floating button with a gap
    between them, which read as two unrelated controls stranded either side of
    the page. Centred as one row with a real gap, they read as what they are:
    the two ways off this screen, both secondary.
*/
.sms-activation-step .form-buttons {
    max-width: 460px;
    margin: 1.25rem 0 0;
    display: flex;
    align-items: center;
    /* Left with the card above them, and still level with each other. */
    justify-content: flex-start;
    gap: 24px;
}



@media (max-width: 479px) {
    .sms-verify { padding: 1.5rem 1.25rem; }
    .sms-verify__boxes { gap: 6px; }
    .sms-verify__box { width: 44px !important; height: 54px; font-size: 1.25rem; }
}

/*
    Only rendered when the send failed, so it can afford to be loud. Uses the
    theme's own error red rather than a new colour.
*/
.sms-verify__error {
    margin: 0 0 1.25rem;
    font-size: 0.9375em;
    line-height: 1.5;
    color: #d93025;
}


/*
    "We do not have a number for you" - the phone entry on the verification step.

    Same card, same rhythm as the code boxes it replaces, so the screen does not
    change shape when one is swapped for the other.
*/
.sms-verify__phone {
    margin-top: 0.5rem;
}

.sms-verify__phone-text {
    margin: 0 0 1rem;
    font-size: 0.9375em;
    line-height: 1.5;
    color: var(--cat-link-color, #777);
}

/*
    The intl-tel-input wrapper is injected around the input at runtime, so the
    width has to be set on the wrapper too - styling only the input leaves the
    country picker sitting in a box of its own width.
*/
.sms-verify__phone .iti,
.sms-verify__phone-input {
    width: 100% !important;
    max-width: 260px;
}

.sms-verify__phone .iti { margin: 0 auto 1rem; display: block; }

.sms-verify__phone-input {
    height: 44px;
    text-align: left;
    border: 1px solid var(--highlight-border-color, #d4d4d4);
    border-radius: 8px;
    background: var(--body-background-color, #fff);
    color: var(--body-font-color, #111);
}

.sms-verify__phone-input:focus {
    outline: none;
    border-color: var(--noiz-dark-orange, #ee6820);
    box-shadow: 0 0 0 3px rgba(238, 104, 32, 0.18);
}

.sms-verify__phone .phone-field-error {
    display: block;
    margin-bottom: 0.75rem;
    font-size: 0.8125em;
}


/*
    "This listing is NOT published yet" on the last step of the wizard.

    Deliberately the loudest thing on a page full of prices: the wizard has
    finished, the heading says "Νέα καταχώριση", and everything about the layout
    says done. It is not done, and somebody who leaves here has no listing.

    Amber rather than red - this is not an error, and red next to a payment form
    reads as "something went wrong with your card".
*/
.promote-not-published {
    max-width: 900px;
    margin: 0 auto 1.5rem;
    padding: 14px 18px;
    border: 1px solid #f0c36d;
    border-left: 4px solid #e8a317;
    border-radius: 8px;
    background: rgba(232, 163, 23, 0.10);
    color: var(--body-font-color, #111);
    font-size: 0.9375em;
    line-height: 1.55;
}


/*
    The Settings page.

    Spacing follows the Offers page (.offers-page__group, 36px between blocks)
    so the two account pages feel like the same site. The default here was
    nothing at all: heading, sentence and control ran together in one grey mass
    because none of these elements carries margin of its own.

    The control row is a flex row rather than an inline select followed by a
    button, so the gap between them is stated once and does not depend on the
    whitespace between two tags.
*/
.member-settings__group {
    max-width: 640px;
    margin-bottom: 36px;
}

.member-settings__group + .member-settings__group {
    padding-top: 32px;
    border-top: 1px solid var(--highlight-border-color, #d4d4d4);
}

.member-settings__heading {
    margin: 0 0 12px;
    font-size: 1.25rem;
    font-weight: 700;
}

/*
    A readable measure for the explanation, and real space under it. 1.55 line
    height matches the notice on the promote step - this is the same kind of
    text, a sentence explaining what a control does.
*/
.member-settings__text {
    margin: 0 0 24px;
    color: var(--cat-link-color, #777);
    font-size: 0.9375em;
    line-height: 1.55;
}

.member-settings__control {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 16px;
}

.member-settings__control select {
    min-width: 320px;
}

/* Narrow screens: the select takes the width and the button sits under it. */
@media screen and (max-width: 480px) {
    .member-settings__control select {
        min-width: 0;
        width: 100%;
    }

    .member-settings__control input[type="submit"] {
        width: 100%;
    }
}


/*
    The optional email field on the report box, for guests.

    The input is the same height as a real form field rather than the browser
    default - it sits under a full-width textarea, and a squat little box beside
    it reads as an afterthought nobody is meant to fill in.

    The note under it is deliberately NOT .notice_message: that class is the
    site's warning colour, and "we only use this to tell you we got it" is
    reassurance, not a warning.
*/
#reporter-mail input[type="email"] {
    /*
        The theme styles input[type=text|search|password|number] and textarea,
        and stops there - an email input inherits none of it and renders as a
        bare browser box with no background at all, which under a filled grey
        textarea looks like a rendering fault rather than a field.

        Same treatment as every other field, two pixels taller than the
        theme's 40 because it sits alone under a large textarea.
    */
    width: 100%;
    height: 44px;
    border: 2px solid transparent;
    background-color: var(--form-background-color);
    color: var(--body-font-color);
    font-family: "Onest", sans-serif;
    font-size: 0.9375em;
    padding: 0 12px;
    border-radius: 8px;
    -webkit-appearance: none;
    -moz-appearance: none;
    transition: background-color var(--duration) var(--timing), border-color var(--duration) var(--timing);
}

#reporter-mail input[type="email"]:focus {
    border-color: var(--highlight-border-color, #d4d4d4);
}

.rbl-email-note {
    margin-top: 6px;
    color: var(--body-font-color, #111);
    font-size: 0.8125em;
    line-height: 1.45;
}

/* ---------------------------------------------------------------------------
   Saved searches page

   The criteria used to render as stacked from/to statements padded out with
   "Οποιαδήποτε"; they are chips now, one per criterion, and the status word is
   a notify switch. See tpl/blocks/saved_search_criteria.tpl for the why.
   --------------------------------------------------------------------------- */

.ss-intro {
    margin: 0 0 18px;
    max-width: 70ch;          /* a paragraph, not a banner - stop it running the full width */
    color: #5a6472;
    line-height: 1.5;
}

.ss-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.ss-chip {
    display: inline-flex;
    align-items: baseline;
    gap: 5px;
    padding: 3px 9px;
    border: 1px solid #e2e6ea;
    border-radius: 14px;
    background: #f7f9fa;
    font-size: 13px;
    line-height: 1.6;
}

.ss-chip__label {
    color: #7b8794;
}

.ss-chip__label:after {
    content: ':';
}

.ss-chip__value {
    color: #2b3440;
    font-weight: 600;
}

/*
    The theme truncates a checkbox label to one line - overflow:hidden plus
    text-overflow:ellipsis on input + label. That is right for a form field and
    wrong in a 230px column, where "Ειδοποίησέ με για νέα αποτελέσματα" became
    an ellipsis. Let it wrap; the box keeps its own line because the theme's
    span is inline-block with a right margin.
*/
.ss-notify > label {
    overflow: visible;
    text-overflow: clip;
    white-space: normal;
    line-height: 1.4;
    font-size: 13px;
}

.ss-notify > input:disabled + label {
    cursor: progress;          /* the switch round-trips to the server before it means anything */
    opacity: 0.6;
}

/*
    The switch is the whole cell now - no wording, because the column heading
    says "Ειδοποιήσεις" and repeating it on every row was a sentence per line.
    The label keeps a title and the input an aria-label, so it is neither a
    mystery on hover nor an unnamed control to a screen reader.
*/
.ss-notify > label > span {
    margin-right: 0;
}

/*
    Actually centre the notifications column. The theme's .center class only
    does 'padding-right: 0' on a list-table cell - it does not touch alignment -
    so the header word and the checkbox under it were both sitting left.
*/
#saved_search > div > div.status-cell,
#saved_search > div.header > div.center {
    text-align: center;
}

/*
    Every cell centred on its row.

    div.list-table is a real table (display: table / table-row / table-cell) and
    the theme sets vertical-align: top on row cells, which is right when a cell
    holds a stacked block. Here the tallest cell is the criteria chips, which
    can wrap to two lines, and everything else - the number, the date, the
    results link, a 20px checkbox - hung from the top edge against it.

    Scoped to this table: the same list-table renders My Listings and the
    message list, where top alignment is what those want.
*/
#saved_search > div.row > div {
    vertical-align: middle;
}

/*
    The results link sits in its own column now rather than under the date. The
    theme's .text rule greys out and shrinks anything in a date cell, which is
    right for the date and wrong for a link somebody is meant to click.
*/
.ss-results-cell > a.do-search {
    font-size: 0.9375em;
    white-space: nowrap;
}

/*
    Mass actions as buttons. The theme's pipe separator between them is for
    links; with real buttons it renders a stray "|" floating between two of
    them.
*/
#saved_search_obj .mass-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    align-items: center;
}

#saved_search_obj .mass-actions > a:not(:last-child):after {
    content: none;
    padding: 0;
}

#saved_search_obj .mass-actions > a.btn {
    height: 36px;
    padding: 0 16px;
    text-decoration: none;
}

/*
    One appearance for all three: white, a light rounded border, dark text.

    Values are the theme's own rather than new ones - --plans-border-color is
    the same #d4d4d4 the table's header rule uses, --body-font-color the same
    #111 as body copy, and 8px is the radius every other control on the site
    has. .btn is filled dark by default, so each of those has to be set back
    explicitly; overriding the colour alone put dark text on near-black, which
    is how the delete button looked when it was styled that way.
*/
#saved_search_obj .mass-actions > a.ss-btn {
    background-color: #fff;
    border: 1px solid var(--plans-border-color);
    border-radius: 8px;
    color: var(--body-font-color);
    font-family: "Onest", sans-serif;
    font-size: 0.9375em;
    height: 36px;
    padding: 0 16px;
    text-decoration: none;
}

#saved_search_obj .mass-actions > a.ss-btn:hover {
    background-color: #f7f7f8;
    border-color: var(--form-field-line-color-hover);
    color: var(--body-font-color);
}

/*
    The saved-search panel used to be forced white here, back when
    --content-background-color was still #F3F2F4. That variable is white in
    light.css now, which does the same thing for every panel, so the override
    is gone rather than left to shadow it.
*/

/* ---------------------------------------------------------------------------
   Account menu group headings

   The menu is seventeen items and reads as three things: who you are, what you
   have listed, what you have paid. The headings are labels, not links - no
   hover, no pointer, and they sit outside the tab order.
   --------------------------------------------------------------------------- */

.sidebar-account-menu > li.udm-menu-group,
.udm-menu > li.udm-menu-group {
    padding: 18px 0 6px 12px;
    font-size: 0.8125rem;
    font-weight: 700;
    /*
        Near-black, not the muted grey used for secondary text. A heading that
        is quieter than the items under it stops working as a heading - it
        reads as a note about the first item rather than as the name of the
        group. --body-font-color is the same #111 as body copy.
    */
    color: var(--body-font-color, #111);
    cursor: default;
    pointer-events: none;      /* a heading is not a target */
}

/*
    Deliberately not uppercased. It is the obvious treatment for a section
    label, but CSS uppercasing of Greek is a trap: the rule is that a
    capitalised word drops its tonos, "Λογαριασμός" to "ΛΟΓΑΡΙΑΣΜΟΣ", and
    whether text-transform does that correctly depends on the browser. Bold at
    a smaller size separates the heading from the items on its own.
*/

/* The first heading has the welcome line above it and needs no gap of its own. */
.sidebar-account-menu > li.udm-menu-group:first-child,
.udm-menu > li.udm-menu-group:first-child {
    padding-top: 4px;
}

.sidebar-account-menu > li.udm-menu-group:hover,
.udm-menu > li.udm-menu-group:hover {
    background: none;
}

/*
    The dropdown is tighter than the sidebar - it is a popover, not a column -
    so the headings get less air above them there.
*/
.udm-menu > li.udm-menu-group {
    padding: 12px 0 4px 14px;
}

/*
    "NEW!" next to a menu item.

    Deliberately unlike .udm-badge, which is a count and carries information -
    this one is an advertisement, so it is smaller, it is not a circle, and it
    does not sit where the eye looks for a number.
*/
.udm-new {
    margin-left: auto;
    padding: 1px 6px;
    border-radius: 4px;
    background: var(--noiz-light-orange, #f0821e);
    color: #fff;
    font-size: 0.625rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    line-height: 1.6;
    white-space: nowrap;
}

/*
    The account sidebar opens with the member, not a greeting.

    Same markup and classes as the header dropdown (blocks/user_navbar.tpl), so
    almost all of it is already styled. Only the padding differs: the dropdown
    is a popover and gives itself 20px all round, while here the block supplies
    its own and the header has to line up with the menu items under it, whose
    text starts at 12px.
*/
.account-menu-header.udm-header {
    padding: 0 0 16px 12px;
    margin-bottom: 6px;
    border-bottom: 1px solid var(--plans-border-color, #d4d4d4);
}

/* 48px is right in a popover; in a sidebar column it crowds the first group. */
.account-menu-header .udm-avatar .avatar-initials,
.account-menu-header .udm-avatar .avatar-image {
    width: 40px;
    height: 40px;
    font-size: 1rem;
}

.account-menu-header .udm-view-profile {
    color: var(--info-field-color, #7b8794);
}

/* ---------------------------------------------------------------------------
   Avatar section in Ρυθμίσεις προφίλ

   The widget's own styling comes from controllers/profile/profile.css, which
   scopes it to .my-profile-sidebar - hence that class still being on the
   wrapper. Only the section framing is new.
   --------------------------------------------------------------------------- */

.profile-avatar-block {
    margin-bottom: 30px;
    padding-bottom: 24px;
    border-bottom: 1px solid var(--plans-border-color, #d4d4d4);
}

.profile-section-title {
    margin: 0 0 14px;
    font-size: 1rem;
    font-weight: 700;
    color: var(--body-font-color, #111);
}

/*
    In the sidebar the preview was 110x140, a portrait box sized for a narrow
    column. In the tab there is room, and a square reads as an avatar rather
    than as a photo of something.
*/
.profile-avatar-section .image-preview-wrapper .image-preview {
    width: 140px;
    height: 140px;
}

.profile-avatar-section .image-preview-wrapper .image-preview img {
    border-radius: 10px;
}

/* ---------------------------------------------------------------------------
   Danger Area tab

   The delete-account button used to sit at the bottom of the sidebar box with
   no explanation. Here it gets a sentence and some room around it.
   --------------------------------------------------------------------------- */

.profile-danger-area {
    max-width: 60ch;
}

.profile-danger-intro {
    margin: 0 0 20px;
    line-height: 1.55;
    color: var(--body-font-color, #111);
}

.profile-danger-area .account-removing {
    margin: 0;
}

/* ---------------------------------------------------------------------------
   Footer block area

   The "Footer" placement: full width, immediately above the site footer, with
   the gap Alex asked for so a banner does not sit flush against it.
   --------------------------------------------------------------------------- */

.footer-blocks {
    margin: 40px 0 48px;
}

.footer-blocks > .point1 {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 20px;
}

/* A banner block brings its own section wrapper; it should not add a card. */
.footer-blocks section.side_block {
    width: 100%;
    padding: 0;
    background: none;
    margin-bottom: 0;
}

@media screen and (max-width: 767px) {
    .footer-blocks {
        margin: 28px 0 32px;
    }
}

/* ==========================================================================
   HOME HERO
   From the design handoff of 2026-08-15. Replaces the carousel.

   Values are the handoff's, moved out of its inline styles so they live where
   the rest of the site's design does. The photograph is an <img> rather than a
   background-image on purpose: the browser's preloader finds it in the markup
   and starts it before the stylesheet is parsed, which for the one image that
   defines the top of the homepage is the difference worth having. width and
   height are on the tag so it reserves its space and nothing below it jumps.
   ========================================================================== */

.home-hero {
    position: relative;
    /* A 26px band of page above the hero, so the header keeps the white space
       under it instead of the photograph starting flush against the search bar.
       On margin rather than padding: the gap belongs to the page, not to the
       hero, so the photograph and its gradients still reach the hero's own top
       edge. */
    margin-top: 26px;
    /* 520, after 640 (the handoff) and 560. Each cut has come out of empty
       photograph rather than out of the content, which is why the block keeps
       reading the same while getting shorter. */
    height: 520px;
    min-height: 380px;
    display: flex;
    /* stretch, not center: the inner column now decides where things sit
       vertically, and it cannot do that inside a box shrunk to its content. */
    align-items: stretch;
    overflow: hidden;
    background: rgb(18, 18, 18);
}

.home-hero__photo {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    /*
        Weighted right and high.

        Right, because the subject sits right of centre and the text column sits
        left, so the crop keeps them out of each other's way at every width.

        High, because of arithmetic: the photograph is 16:9 and the hero band is
        about 2.6:1, so at 1440 the image renders 810px tall into 560px and 31%
        of its height is cropped away. Centred, that takes 15% off the top -
        and the guitarist's head starts at 4%, so centring decapitates him. 18%
        keeps the face with room above it.
    */
    object-position: 60% 18%;
}

/* Two gradients, not one. The vertical pass darkens the whole frame so white
   text is legible anywhere; the horizontal pass deepens the left third, where
   the words actually are. One gradient doing both jobs either washes out the
   photograph or loses the headline. */
.home-hero__overlay {
    position: absolute;
    inset: 0;
    /*
        RETUNED FOR A BLACK-AND-WHITE PHOTOGRAPH.

        The first version was drawn over a warm, dim, low-contrast image and
        used rgb(16,12,9) - a brown-black - at up to 0.92. Over a monochrome
        photograph that did two things wrong: it tinted a black-and-white image
        sepia, and it buried the subject, who is the reason for the picture.

        Now neutral (18,18,18), and lighter on the right where the guitarist is:
        0.24 at the far edge instead of 0.35. The left stays heavy - 0.94 - so
        the headline keeps the same contrast it had, which is the half of this
        that is not negotiable.

        The bottom pass is halved. It existed to stop the old photograph's
        bright floor fighting the pills; this crop has no floor in it.
    */
    background:
        linear-gradient(to right, rgba(18, 18, 18, 0.94) 0%, rgba(18, 18, 18, 0.76) 42%, rgba(18, 18, 18, 0.24) 100%),
        linear-gradient(to top, rgba(18, 18, 18, 0.45) 0%, rgba(18, 18, 18, 0.12) 55%, rgba(18, 18, 18, 0.3) 100%);
}

/*
    The column that decides the vertical layout.

    The headline sits near the top and the popular searches sit near the bottom,
    rather than everything being centred as one lump with the pills floating in
    the middle of the frame. margin-top:auto on the pills takes the free space,
    which is what puts them at the bottom edge - and it does nothing at all on a
    phone, where the hero is auto-height and there is no free space to take.
*/
.home-hero__inner {
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: center;
    width: 100%;
    max-width: 1200px;
    margin: 0 auto;
    /*
        30 top, 34 bottom, on a hero whose height is fixed at 520px - so these
        two and the gap above the popular searches are one sum, not three
        independent numbers:

            gap = 520 - top - bottom - text height - popular height

        The bottom went to 34 for air under the pills, and the top gave up the
        14 to pay for it. Spending it out of the gap instead would have undone
        the change immediately before this one, and spending it by growing the
        hero would have undone three rounds of making it shorter.

        The only visible cost is the kicker starting 14px higher, which is what
        the space under the pills is worth.
    */
    padding: 30px 40px 34px;
}

.home-hero__text {
    display: flex;
    flex-direction: column;
    gap: 18px;
    max-width: 620px;
}

.home-hero__kicker {
    display: flex;
    align-items: center;
    gap: 12px;
    color: #ffb08a;
    font-size: 14px;
    font-weight: 700;
    letter-spacing: 2.5px;
    text-transform: uppercase;
}

.home-hero__kicker-bar {
    display: block;
    width: 34px;
    height: 2px;
    background: #ee6820;
}

.home-hero__title {
    margin: 0;
    color: #fff;
    font-size: 56px;
    font-weight: 900;
    line-height: 1.05;
    letter-spacing: -1.5px;
}

.home-hero__lead {
    margin: 0;
    max-width: 520px;
    color: rgba(255, 255, 255, 0.85);
    font-size: 18px;
    line-height: 1.6;
}

.home-hero__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    margin-top: 4px;
}

/* WHY EVERY ANCHOR RULE BELOW IS WRITTEN ".home-hero a.home-hero__cta"
   RATHER THAN JUST THE CLASS

   style.css line 247 styles "a:link, a:visited", which is specificity (0,1,1)
   and therefore beats a bare class at (0,1,0). Rendered locally that put the
   site's orange link colour on orange buttons - the label all but vanished. The
   parent class takes these to (0,2,1), which wins honestly, without !important
   and without touching a rule the whole site depends on. */

.home-hero a.home-hero__cta {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    padding: 14px 26px;
    border-radius: 10px;
    font-size: 16px;
    font-weight: 700;
    text-decoration: none;
    transition: transform .15s ease, background-color .15s ease, box-shadow .15s ease;
}

.home-hero a.home-hero__cta:hover,
.home-hero a.home-hero__cta:focus {
    text-decoration: none;
    transform: translateY(-1px);
}

.home-hero a.home-hero__cta--primary {
    background: #ee6820;
    color: #fff;
    box-shadow: 0 8px 24px rgba(238, 104, 32, 0.35);
}

.home-hero a.home-hero__cta--primary:hover,
.home-hero a.home-hero__cta--primary:focus {
    background: #f2762f;
    color: #fff;
    box-shadow: 0 10px 28px rgba(238, 104, 32, 0.45);
}

.home-hero a.home-hero__cta--ghost {
    background: rgba(255, 255, 255, 0.12);
    border: 1.5px solid rgba(255, 255, 255, 0.25);
    color: #fff;
    /* Progressive: without support the panel is simply flat, which is fine. */
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
}

.home-hero a.home-hero__cta--ghost:hover,
.home-hero a.home-hero__cta--ghost:focus {
    background: rgba(255, 255, 255, 0.2);
    border-color: rgba(255, 255, 255, 0.4);
    color: #fff;
}

.home-hero__stats {
    display: flex;
    flex-wrap: wrap;
    gap: 40px;
    margin-top: 10px;
    /*
        The rule that used to sit here is gone - the numbers separate themselves
        perfectly well from the buttons above them.

        The 20px it was there to hold off stays. Without the line the padding is
        just spacing, and removing it too would take 20px out of the text
        column, which on a fixed-height hero is 20px that would reappear as gap
        above the popular searches - a block nobody asked to move.
    */
    padding-top: 20px;
}

.home-hero__stat {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.home-hero__stat-value {
    color: #fff;
    font-size: 24px;
    font-weight: 800;
    line-height: 1.2;
}

.home-hero__stat-label {
    color: rgba(255, 255, 255, 0.6);
    font-size: 13px;
}

.home-hero__popular {
    /* auto rather than a number: it absorbs whatever height is left over, so
       the pills stay on the bottom edge at 520px and would still do so if the
       hero changed again. */
    margin-top: auto;
    /*
        The air above "ΔΗΜΟΦΙΛΕΙΣ ΑΝΑΖΗΤΗΣΕΙΣ", and it only does the work on a
        narrow window.

        At 520px the auto margin above has already taken the leftover height -
        measured at 15.8px on a 1280px screen - so raising this number there
        just moves height from the margin into the padding and the label does
        not move. Below 768px the hero is auto-height, there is no leftover, and
        this is the whole gap: it was 26px against the desktop's 42.

        40 rather than more because the desktop slack is what limits it: past
        ~42 the padding would win, the column would outgrow the fixed 520px, and
        the pills would hang below the photograph.
    */
    padding-top: 40px;
}

.home-hero__popular-label {
    margin-bottom: 12px;
    color: rgba(255, 255, 255, 0.55);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 1.5px;
    text-transform: uppercase;
}

.home-hero__pills {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
}

/*
    ONE ROW ON DESKTOP, WHATEVER THE TERMS ARE.

    Clamped by height rather than by counting pills, because the pills are as
    wide as the words in them: "PRS" and "Fender Stratocaster" are the same
    element and four times apart in width, so any fixed number that fills the
    line for one month's search terms leaves a gap or a second row the next.

    A pill is 35px tall (8+8 padding, ~17 line, 2 border) and the second row
    would start at 45px, so 40px keeps exactly one row at every width and the
    surplus terms simply never draw. They stay in the markup - which is what
    makes this hold when the terms change without anybody editing anything.
*/
@media (min-width: 769px) {
    .home-hero__pills {
        max-height: 40px;
        overflow: hidden;
    }
}

.home-hero a.home-hero__pill {
    padding: 8px 16px;
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.08);
    color: rgba(255, 255, 255, 0.9);
    font-size: 14px;
    text-decoration: none;
    transition: border-color .15s ease, background-color .15s ease;
}

.home-hero a.home-hero__pill:hover,
.home-hero a.home-hero__pill:focus {
    border-color: #ee6820;
    background: rgba(238, 104, 32, 0.15);
    color: #fff;
    text-decoration: none;
}

/* The handoff's breakpoint. The fixed height goes first: on a phone the photo
   is doing far less work than the words, and 640px of it pushes every listing
   below the fold. */
@media (max-width: 768px) {
    .home-hero {
        height: auto;
        min-height: 0;
        /*
            60 at the bottom, was 44. Free to give here in a way it is not on a
            desktop screen: the hero is auto-height below this breakpoint, so
            padding under the pills makes the photograph taller instead of
            competing with the gap above them.
        */
        padding: 56px 0 60px;
    }

    .home-hero__inner {
        padding: 0 20px;
    }

    /*
        The 620px cap comes off here, or "centred" is not centred on a tablet.

        Everything in the hero lives inside this column, so a centred row is
        centred on the column rather than on the screen. Below about 660px the
        column has already run out of room and the two are the same thing - at
        570px both centres measure 285 - but at 768px the column stops 108px
        short of the right edge and the stats sit visibly left of the middle.

        The cost is the headline and lead being allowed those 108px on a tablet,
        which is where a 620px column hugging the left edge looked odd anyway.
    */
    .home-hero__text {
        max-width: none;
    }

    .home-hero__title {
        font-size: 40px;
        letter-spacing: -1px;
    }

    .home-hero__lead {
        font-size: 16px;
    }

    .home-hero a.home-hero__cta {
        flex: 1 1 auto;
        justify-content: center;
    }

    /*
        Centred from here down, and only from here down.

        The headline, the lead and the button stay left-aligned - they read as a
        column of text and centring them would set every line adrift. The two
        blocks below them are not text: three numbers and a row of pills, both
        of which sit in the middle of a narrow screen far better than they hang
        off its left edge.

        text-align rather than align-items, because each stat is itself a
        column: the value and its caption both have to move, not just the
        stat's box.
    */
    .home-hero__stats {
        gap: 24px;
        justify-content: center;
        text-align: center;
    }

    .home-hero__popular {
        text-align: center;
    }

    .home-hero__pills {
        justify-content: center;
    }

    /* Twelve pills is four rows on a phone, and the hero stops being a hero.
       The tail is hidden rather than fetched differently so the markup, the
       cache and the desktop row stay one thing. */
    .home-hero__pill:nth-child(n+7) {
        display: none;
    }

    .home-hero__stat-value {
        font-size: 22px;
    }
}

@media (max-width: 480px) {
    .home-hero__title {
        font-size: 34px;
    }

    /*
        This block used to set space-between, which is what centring has to
        replace rather than sit beside - it comes later in the file and would
        otherwise win below 480px.

        It was doing harm on its own: at 390px the three stats do not fit on one
        line, so "100%" wrapped to a second row while space-between shoved the
        two above it against opposite edges, leaving a hole down the middle.
        Centred, the wrap reads as two rows of a group.
    */
    .home-hero__stats {
        justify-content: center;
    }
}

/* Somebody who has asked their system to stop moving things gets a hero that
   does not lift under the cursor. */
@media (prefers-reduced-motion: reduce) {
    .home-hero a.home-hero__cta {
        transition: none;
    }

    .home-hero a.home-hero__cta:hover,
    .home-hero a.home-hero__cta:focus {
        transform: none;
    }
}

/* ==========================================================================
   HEADER WEIGHT
   The new hero is heavy and dark, and next to it the header read thin.
   Three adjustments, all of them scoped to the header so no form or link
   elsewhere on the site changes.
   ========================================================================== */

/* The top strip sits at 300 - Onest Light, a real cut of the family rather than
   a synthesised one, so it thins without going grey or blurry. Tried 600 and
   then 400 first; both made the strip compete with the navigation row below it
   rather than sit above it. Set explicitly rather than left to inherit, so it
   cannot drift with the body font. The header takes its weight from the logo
   and the outlined search box instead. */
.top-header .main-menu a {
    font-weight: 300;
}

/* The page you are on, and only that one. 400 everywhere else means 600 here
   reads as position rather than emphasis - it is the same signal the marker bar
   above the item is giving, said twice. */
.top-header .main-menu a.active {
    font-weight: 600;
}

/*
    The search box: border instead of fill.

    Every input on the site takes --form-background-color, which is #e2e2e2 in
    light and #555 in dark - a solid grey slab across the widest element in the
    header. Outlined, the header reads as one row of controls rather than one
    grey block with things either side of it.

    Written "input.smart-search__input" rather than the bare class because
    style.css styles input[type="text"] at (0,1,1) and a class alone at (0,1,0)
    would lose. This wins on specificity, not on !important, and it is scoped to
    the header's own search field - every other input on the site keeps its
    fill.
*/
input.smart-search__input,
input.smart-search__input:hover {
    background-color: transparent;
    /*
        THE SAME LINE AS THE BUTTON NEXT TO IT.

        First written as 2px of --form-field-line-color-hover, which is what
        every input on the site uses - and beside "Σύνδεση/Εγγραφή" at 1px of
        --highlight-border-color it read as a heavier, darker box, so the header
        had two different ideas of what an outline is. Matched to the button:
        same width, same variable, so the three outlined controls in that row
        are drawn with one line.
    */
    border: 1px solid var(--highlight-border-color, #d4d4d4);
}

/* Focus still belongs to the theme's focus colour - the point was to remove the
   fill, not the affordance. Kept at 1px so focusing does not nudge the text
   inside by a pixel. */
input.smart-search__input:focus {
    background-color: transparent;
    border: 1px solid var(--form-field-line-color-focus);
}

/* 52, and 48 on the narrow layout, keeping the two in proportion so the header
   does not change shape at the breakpoint. The mark has been 64, 60, 56 and now
   here - every step judged against the real header rather than in the abstract. */
div#logo img {
    height: 56px;
}

@media (max-width: 1199px) {
    div#logo img {
        height: 52px;
    }
}

/*
    The search field runs the full width of its column.

    It was capped at 640px above 1200 to put air between it and the account
    controls. The header has changed around it since - "Όλες οι κατηγορίες"
    became "Όλα", the buttons became outlined pills, the mark got smaller - and
    the row no longer reads as crowded, so the cap was leaving a hole in the
    middle of the header rather than a separation at the end of it.
*/

/* ==========================================================================
   HEADER BUTTONS: OUTLINED AND FULLY ROUNDED
   The two right-hand controls were a bordered rectangle and a solid orange
   rectangle. Both become pills drawn with a line only, so the whole header is
   one visual language - the same one the hero's popular-search pills use.
   ========================================================================== */

.header-auth-btn {
    border-radius: 999px;
}

/*
    "Νέα καταχώριση" matches "Σύνδεση/Εγγραφή", and carries more weight.

    style.css gives .add-property a two-stop orange gradient with
    `color: white !important` and `border: 0 !important`, inside a min-width:768
    block - so every declaration here needs !important of its own to reach it.
    That is not decoration: it is the only way to override a rule that used
    !important first, and custom.css loads last so equal weight resolves here.

    Same line and same colours as the button beside it - --highlight-border-color
    and the body text colour, both taken from the same variables
    .header-auth-btn uses, so the pair stays matched if either is retuned.

    The two are separated by weight instead: 600 against the auth button's 500.
    That is enough to read as the primary action in a row of two identical
    shapes, and it is the cheapest possible difference - no second colour, no
    second shape, nothing for a reader to decode.
*/
.add-property,
a.button.add-property {
    background: transparent !important;
    border: 1px solid var(--highlight-border-color, #d4d4d4) !important;
    border-radius: 999px !important;
    color: var(--body-font-color, #111) !important;
    /* 500, the same as the sign-in link beside it. 600 was doing the work of
       distinguishing the two when both were outlined pills; the sign-in link is
       plain text now, so the shapes already say which one is the action and the
       extra weight only made the label heavy. */
    font-weight: 500 !important;
    padding: 0 22px !important;
}

/* The same hover the auth button has, for the same reason: the pair should
   behave identically as well as look identical. */
.add-property:hover,
a.button.add-property:hover {
    background: rgba(127, 127, 127, 0.14) !important;
    border-color: var(--body-font-color, #111) !important;
    color: var(--body-font-color, #111) !important;
}

/* The "+" was a :before pseudo-element on the same rule. Removed with its
   spacing, so the label centres in the pill rather than sitting off to one
   side. */
.add-property:before,
a.button.add-property:before {
    content: none !important;
    margin: 0 !important;
}

/*
    No outline until it is doing something.

    Closed, this is a label with an icon - the search field beside it already
    draws the boundary for that pair, and a second box around the words was one
    border too many in a row that now has very few. Open, it fills (see the
    rule further down), which is where a defined edge earns its place.

    The radius stays 8px to match the search field for the filled state.
*/
.category-menu__button {
    border-radius: 8px;
}

/*
    "Όλα" inverts: outlined at rest, filled while open.

    It was the only filled control left in the header - a black slab beside
    three outlined pills - and it was filled all the time, which spends the
    strongest treatment in the row on a control that is doing nothing yet.

    So the fill now means something: closed is an outline like everything else,
    open is solid. That is the state the fill was always describing; it just was
    not being told when to stop.

    .category-menu__button_opened is toggled onto the button itself by the
    script in menus/category_menu_content.tpl - which is why this needs no
    markup change and no JavaScript of its own. The container's own _opened
    class could not have been used: the container is a sibling that comes after
    the button in the DOM, and CSS cannot select backwards.

    The declarations each undo one thing the button inherits - background, text
    colour, and the icon bars, which take --button-text-color separately
    because they are drawn as pseudo-elements rather than text.

    The !important on background is forced: light.css sets
    `.category-menu__button { background: #1d1d1d !important }` - hard-coded,
    not a variable, so in light mode this button was black no matter what the
    theme said. Equal specificity plus !important resolves by order, and
    custom.css loads last. The shorthand is used rather than background-color
    to match what is being overridden.
*/
.category-menu__button {
    background: transparent !important;
    border: 0;
    color: var(--body-font-color, #111);
    /* border:0 removes the 1px the box was drawn with, so the label would shift
       a pixel against the search field beside it without this. */
    padding: 0 15px;
}

.category-menu__button .category-menu__button-icon span,
.category-menu__button .category-menu__button-icon span::before,
.category-menu__button .category-menu__button-icon span::after {
    background: var(--body-font-color, #111);
}

/* With no border to tint, hover shows the fill it is about to become - at a
   fraction of the strength, so it reads as a preview rather than a state. */
.category-menu__button:hover {
    background: rgba(127, 127, 127, 0.12) !important;
}

/* Open: the original treatment, now earning its weight. */
.category-menu__button.category-menu__button_opened {
    background: var(--button-color) !important;
    border: 1px solid var(--button-color);
    color: var(--button-text-color);
}

.category-menu__button.category-menu__button_opened .category-menu__button-icon span,
.category-menu__button.category-menu__button_opened .category-menu__button-icon span::before,
.category-menu__button.category-menu__button_opened .category-menu__button-icon span::after {
    background: var(--button-text-color);
}

/*
    THE LOGO'S ROW: ONE HEIGHT, AND A LARGER ONE.

    Όλα, the search field and the two buttons were all exactly 40px - already
    matched, just small beside a 60px logo, which left the row looking like
    controls parked under a mark rather than a row of equals. 46 closes most of
    that gap without turning the header into a toolbar.

    Everything here is scoped to .top-navigation, which is the wrapper holding
    the logo, the category button, the search field and the account controls.
    That scope is the whole point: `.btn` and `input[type="text"]` are 40px
    site-wide, and a bare override would have resized every button and every
    form field on every page to suit the header.

    One number, applied to all four, so they cannot drift apart later: change 46
    here and the row stays a row.
*/
.top-navigation .category-menu__button,
.top-navigation input.smart-search__input,
.top-navigation .header-auth-btn,
.top-navigation a.button.add-property {
    height: 46px;
}

/* The category button centres its label with line-height rather than flex
   alignment, so it needs the number twice. */
.top-navigation .category-menu__button {
    line-height: 46px;
}

/*
    No filter override here, deliberately - and this is worth a note because it
    was overridden for one commit.

    style.css applies `filter: var(--logo-filter)` to the header mark, which
    dark.css sets to invert(0.87). That exists so a near-black disc reads on a
    dark header. The orange mark briefly used here needed the filter switched
    off, since inverting orange returns cyan; the current mark is near-black
    again, so the theme's filter is correct and is left alone.

    If the mark ever becomes coloured again, this is the thing to switch off.
*/

/* ==========================================================================
   THE SIGNED-IN AVATAR: ROW HEIGHT, AND BRAND ORANGE
   ========================================================================== */

/*
    The initial, scaled to whatever --header-avatar currently is. em rather than
    rem so it follows the disc instead of being a third number to remember.
*/
.header-avatar .avatar-initials {
    font-size: 0.95rem;
}

/*
    Brand orange instead of the letter palette.

    style.css assigns a colour per initial - .avatar-initials[data-name*="A"] is
    #e91e63, which is where the pink came from. That palette earns its keep in a
    message list, where a column of different people should be told apart at a
    glance. It earns nothing in the header, where there is exactly one person
    and the colour they get is decided by how their name happens to be spelled.

    So this is scoped to .header-avatar and leaves the palette alone everywhere
    else. The selector carries [data-name] to outrank the per-letter rules,
    which are (0,2,0) against a plain .header-avatar .avatar-initials at (0,2,0)
    - equal, and resolved by order, which would be fragile. With the attribute
    this is (0,3,0) and wins outright.
*/
.header-avatar .avatar-initials[data-name] {
    background: var(--noiz-dark-orange, #ee6820);
    color: #fff;
}

/*
    Manrope ExtraBold, for the section title only.

    The design was drawn in Manrope and the handoff called it a stand-in - but
    it is wanted for real here, and only for this one line, so it is loaded as
    one weight rather than adopted as a second UI family.

    SELF-HOSTED, NOT GOOGLE-LINKED. A <link> to fonts.googleapis.com would put
    every page view's IP in front of a third party for one heading, and add a
    second origin to the critical path. Two files, 19KB together, served from
    the same host as everything else.

    SPLIT BY SCRIPT, WHICH IS THE POINT. The title is entirely Greek, and
    Manrope's Greek coverage was the thing worth checking before agreeing to
    any of this: a font without Greek glyphs would have silently fallen back to
    Onest and the change would have done nothing visible. It has them - the
    greek subset is 5KB, and a Greek reader never downloads the 14KB latin file
    because unicode-range tells the browser not to.

    font-display: swap - the heading is readable in Onest while 5KB arrives,
    rather than invisible.
*/
@font-face {
    font-family: 'Manrope';
    font-style: normal;
    font-weight: 800;
    font-display: swap;
    src: url('../fonts/Manrope-ExtraBold-greek.woff2') format('woff2');
    unicode-range: U+0370-0377, U+037A-037F, U+0384-038A, U+038C, U+038E-03A1, U+03A3-03FF;
}

@font-face {
    font-family: 'Manrope';
    font-style: normal;
    font-weight: 800;
    font-display: swap;
    src: url('../fonts/Manrope-ExtraBold-latin.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+2074, U+20AC, U+2122, U+2191,
                   U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ==========================================================================
   SECTION LOCKUP
   Kicker + title for a content block, from the design of 2026-08-15.
   Applies to any block with a blocks+kicker+<Key> phrase; the first is the
   featured row, which was a bare bold "Προβεβλημένα".
   ========================================================================== */

/*
    WHY EVERY SELECTOR HERE CARRIES .content_block

    style.css has `section.content_block > div h3` at (0,1,3) and matching rules
    on the wrapper div. The lockup puts the heading inside a div, so those rules
    apply to it, and a bare .section-lockup__title at (0,1,0) lost to them
    silently: the title rendered at 21.7px instead of 36 and the gap below
    collapsed to 0. Measured, not guessed - the computed styles were read off
    the live page.

    The wrapper needs more than that: style.css also has
    `section.content_block:not(.no-header) > div` at (0,2,2) setting
    margin-bottom to 0, which beat .content_block .section-lockup at (0,2,0) and
    collapsed the gap under the lockup to nothing. The selector below mirrors
    that rule's shape - section.content_block > div.section-lockup, also (0,2,2)
    - and wins on document order, custom.css being last.

    Both numbers were read off the live page rather than reasoned about: the
    title was rendering at 21.7px and the margin at 0 while the CSS said 36 and
    12.
*/
section.content_block > div.section-lockup {
    display: flex;
    flex-direction: column;
    gap: 10px;

    /*
        PADDING ZERO IS THE WHOLE FIX FOR A 28px INCONSISTENCY.

        style.css has `section.content_block:not(.no-style) > div { padding: 0 0
        28px 0 }`. The lockup is a direct child div, so it collected that
        padding in every section except the two carrying .no-style - which is
        precisely the pair ("Ξεχωρίζουν", "Μόλις ανέβηκαν") that looked right
        while the other seven looked loose. Same selector shape, (0,2,2) against
        (0,2,2), and this wins on order because custom.css loads last.

        No margin-bottom here, on purpose. The gap below the lockup is not this
        element's to set: `body.home-page section.content_block:not(.no-header) >
        div` at (0,3,2) gives the content wrapper a 28px top margin and beats
        anything reasonable declared here. A margin-bottom on this rule computed
        to 0 and did nothing but mislead the next reader.
    */
    padding: 0;
}

.content_block .section-lockup__kicker {
    display: flex;
    align-items: center;
    gap: 10px;
    /* Brand orange, not the design's red.

       The handoff specified #e5332d and pointed at --price-drop as the token to
       map it to. That was the right instinct for a red, but this kicker now
       says "Noiz Featured" - it names the product rather than warning about a
       price - and the site already has one colour for that. Red here would also
       have borrowed the exact hue that means "this got cheaper" everywhere
       else on the site.

       --noiz-light-orange (#FF8200) rather than the darker #ee6820: at 12.5px
       with heavy tracking the darker orange reads muddy, and this is the same
       value the theme already uses for link hovers. */
    color: var(--noiz-light-orange, #ff8200);
    font-size: 12.5px;
    font-weight: 800;
    letter-spacing: 0.14em;
    text-transform: uppercase;
}

.content_block .section-lockup__bar {
    display: block;
    width: 22px;
    height: 3px;
    border-radius: 2px;
    background: var(--noiz-light-orange, #ff8200);
    flex: 0 0 auto;
}

/* The design's ink is #1a1a1a, which is the light theme's body colour. Taken
   from the variable so the title does not stay near-black on a dark page. */
.content_block .section-lockup__title {
    margin: 0;
    /* Onest after Manrope, not a generic stack: if the woff2 fails the heading
       lands on the site's own face rather than on whatever the OS offers. */
    font-family: 'Manrope', 'Onest', sans-serif;
    color: var(--body-font-color, #1a1a1a);
    /* 28. This went 32 (the handoff), 36, back to 32, and down to here:
       Manrope's extrabold sets wider and darker than Onest at the same size, so
       the number that suited the mockup's font is too much for this one. */
    font-size: 28px;
    font-weight: 800;
    letter-spacing: -0.02em;
    line-height: 1.15;
}

/* A 32px title is a desktop size; on a phone it takes three lines away from
   the listings it is introducing. */
@media (max-width: 767px) {
    .content_block .section-lockup__title {
        font-size: 23px;
    }

    /* Nothing to set here either - see the note above on where the gap below
       the lockup actually comes from. */
}

/*
    The avatar inside the account dropdown, matching the one in the header.

    The header's disc went brand orange; this one stayed on the per-initial
    palette, so opening the menu showed the same person in two different
    colours - pink in the panel, orange in the bar that opened it.

    .udm-avatar is the signed-in member's own avatar wherever the account menu
    is drawn: the header dropdown and the sidebar menu. Every other avatar on
    the site - message lists, reviews - keeps the palette, which is where
    telling different people apart actually matters.

    [data-name] takes this to (0,3,0) so it clears three separate rules that
    would otherwise reach it: style.css's .udm-avatar .avatar-initials, the
    per-letter .avatar-initials[data-name*="X"] palette, and dark.css's own
    .udm-avatar .avatar-initials, which sets a slate blue for dark mode. All
    three are (0,2,0).
*/
.udm-avatar .avatar-initials[data-name] {
    background: var(--noiz-dark-orange, #ee6820);
    color: var(--button-text-color, #fff);
}

/*
    The guest's route back to their saved listings.

    An icon with a word under it rather than another pill: the row already has
    two outlined buttons, and a third would make the way to a list look like a
    third action. Stroke only - no border, no fill.

    Still 46px tall, so it sits on the same line as everything else in the row.
*/
/*
    The same text as "Σύνδεση/Εγγραφή", with a heart in front of it.

    Every value here is the auth link's: 0.9375rem at 500 in the body colour,
    which is what .header-auth-btn declares. Two links reading as two links,
    rather than one link and a captioned icon - the caption treatment made the
    heart look like a different kind of control than the words beside it.

    Set explicitly rather than inherited, because .header-auth-btn is a <button>
    and this is an <a>: they share no rule, so the pair would drift the moment
    either was touched.
*/
.top-navigation .header-saved-btn {
    display: inline-flex;
    flex-direction: row;
    align-items: center;
    gap: 7px;
    height: 46px;
    padding: 0 8px;
    margin-right: 8px;
    border: 0;
    background: transparent;
    color: var(--body-font-color, #111);
    font-size: 0.9375rem;
    font-weight: 500;
    white-space: nowrap;
}

.top-navigation .header-saved-btn:hover {
    color: var(--noiz-dark-orange, #ee6820);
}

/*
    Big enough and dark enough to be seen.

    It was drawn in --highlight-border-color at 1px to match the header's
    hairlines, and that was the wrong reference: a border is a boundary you are
    not meant to look at, while this glyph is the only thing telling you what
    the link is. At 18px of #d4d4d4 it disappeared next to the words.

    It now takes the text's own colour, so the icon and the label read as one
    control and the whole thing changes together on hover.

    A fill would close the outline, so it stays none.
*/
.top-navigation .header-saved-btn svg {
    width: 21px;
    height: 21px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.6;
}



/* The label carries no type of its own now - it takes the link's, which is the
   whole point of the change. */
.top-navigation .header-saved-btn__label {
    font: inherit;
}

/*
    "Σύνδεση/Εγγραφή" as plain text, sitting close to the button it precedes.

    Two outlined pills side by side gave a visitor two things of equal weight to
    choose between, when only one of them is the action - the other is the way
    back in for somebody who already has an account. Dropping the outline leaves
    a link next to a button, which is the actual hierarchy.

    The gap goes with the border. The header row is a Bootstrap gap-xl-4 (24px)
    flex line, and that gap is right between unrelated controls; between a label
    and the button it belongs beside, it read as two separate things. The
    negative margin closes it to about 8px - applied to the wrapper rather than
    the button, because the gap is the parent's and this is the only place it
    should be overridden.

    Height stays 46 so the text still sits on the row's centre line, and the
    padding stays small rather than zero so the click target does not shrink to
    the glyphs.
*/
.top-navigation .header-auth-btn {
    border: 0;
    border-radius: 0;
    background: transparent;
    padding: 0 8px;
}

.top-navigation .header-auth-btn:hover {
    background: transparent;
    color: var(--noiz-dark-orange, #ee6820);
}

/*
    Desktop only, and that is the whole point.

    This pulls the sign-in link against "Νέα καταχώριση", which is the control
    it belongs beside. Below 768 that button is hidden (d-none d-md-flex), so
    there is nothing to close the gap to - the -16px just drags the whole
    account column 16px past the container's content edge, and the avatar with
    it. Measured at 390: the search field and category button both end at 375,
    the avatar ended at 391.

    That is the "avatar hanging off the right on phones" bug, arriving for the
    third time by a new route - first the flex column shrinking under its
    content, then the theme's width:0/text-indent:-1000px, now this.
*/
@media (min-width: 768px) {
    .top-navigation .user-navbar {
        margin-right: -16px;
    }

    /*
        Except when somebody is signed in.

        That -16px closes the gap between the sign-in LINK and the button - two
        pieces of text that belong together. A signed-in visitor has an avatar
        there instead, which is a 40px disc, and pulling a disc to within 8px of
        a button reads as a collision rather than a pair. Adding the 16px back
        on the avatar itself restores the row's own 24px gap, and needs no
        :has() or extra class to know which case it is in - the element only
        exists when there is an account.
    */
    .top-navigation .circle.logged-in {
        margin-right: 16px;
    }
}

/*
    Less air above every homepage section.

    style.css sets `.no-sidebar section.content_block { padding: 36px 0 28px }`
    site-wide. On the front page, where nine sections stack one after another,
    that 36px repeated nine times is most of a screen spent on nothing - 18 is
    enough to keep them apart.

    Scoped to body.home-page: category pages and search results have fewer,
    longer blocks where the original spacing still reads correctly. Specificity
    (0,3,1) against the stock rule's (0,2,1).
*/
body.home-page.no-sidebar section.content_block {
    padding-top: 18px;
}


/*
    "Προβολή όλων" sits on the title's line, not the lockup's centre.

    The section is a flex row with align-items: center, so the link was centred
    against the whole header block - which since the lockup arrived means
    centred between the kicker and the title, floating in the gap between them
    and a long way from the row of cards it belongs to.

    align-self: flex-end drops it to the bottom of that block. The arithmetic
    lands where you would want it by hand: the lockup is ~57px (kicker 15, gap
    10, title 32) and the link is ~33px, so ending flush puts its centre at
    ~41px - the title's own centre line.

    Above 768 only. Below that the link is order-3, sitting under the cards
    rather than beside the heading, and has its own margin already.
*/
@media (min-width: 768px) {
    .content_block.has-header-link > a.block-header-link {
        /*
            AUTO MARGINS, NOT align-self.

            align-self: flex-end was tried first and did nothing: the link
            carries Bootstrap's .m-auto, and a vertical auto margin wins over
            align-self in flex layout - the item stays centred whatever the
            alignment says. Measured, the link sat 27px above the title's centre
            in all seven sections, before and after.

            So the auto margin is redirected rather than fought: all of the free
            space goes above the link, none below, which puts it on the bottom
            edge of the header block.

            !important because .m-auto is a Bootstrap utility and those are
            declared with it; nothing short of that reaches.
        */
        margin-top: auto !important;
        margin-bottom: 0 !important;
    }
}

/* ------------------------------------------------------------------
   Category pages: banner in the header, search behind an icon.

   Only pages carrying .category-header reach these; every other page
   keeps the keyword box exactly as it was. Templates:
   tpl/blocks/header_category_bar.tpl (the button, inside the categories
   row) and tpl/blocks/header_category_banner.tpl (the creative and the
   search panel, siblings of that row).
   ------------------------------------------------------------------ */

/*
    The categories button and the search icon stay on the logo row.

    That row holds only those two - roughly 200px with the label, 70 without -
    so it fits beside the logo at any desktop width and the header never shows
    a half-empty first line. Only the banner drops.
*/
.cat-header-row {
    align-items: center;
    flex: 0 1 auto;
    width: auto;
    order: 2;

    /*
        Free space goes after these two, not before them.

        #logo carries Bootstrap's mr-auto, which swallows the whole gap and
        pushes everything after it to the right - on the two-row layout that
        left the categories button and the search icon marooned beside the
        account links, a screen away from the logo they belong next to. Moving
        the auto margin here puts the gap after them instead.

        On one row this changes nothing: the banner's flex-grow takes the free
        space before auto margins ever see it, so the margin resolves to zero
        and the creative still centres in the gap.
    */
    margin-right: auto;
}

body.category-header #logo {
    margin-right: 0 !important; /* the utility is !important; this has to be too */
}

/*
    The search button, in the brand orange the links and the avatar use.
*/
.cat-header-bar__toggle {
    flex: 0 0 42px;
    align-self: center;
    width: 42px;
    height: 42px;
    min-width: 42px;
    padding: 0;
    line-height: 0;
    border: 1px solid var(--noiz-light-orange, #FF8200);
    border-radius: 8px;
    background: transparent;
    cursor: pointer;
    transition: background-color .15s ease, border-color .15s ease;
}

.cat-header-bar__toggle:hover,
.cat-header-bar__toggle:focus-visible,
.cat-header-bar__toggle[aria-expanded="true"] {
    border-color: var(--noiz-dark-orange, #ee6820);
    background: rgba(255, 130, 0, .08);
}

/*
    Stroked, not filled. #magnifying-glass-icon is a bare <path> carrying
    fill="none" and no stroke, exactly like the one smart_search draws in its
    results list. Given a fill it renders an empty box, which is what shipped
    first.
*/
.cat-header-bar__icon {
    width: 18px;
    height: 18px;
    fill: none;
    stroke: var(--noiz-light-orange, #FF8200);
    stroke-width: 2px;
    pointer-events: none;
}

/*
    The banner: beside them when the window allows, a full line below when not.

    Measured with the categories label collapsed: logo 60 + hamburger 30 +
    icon 42 + creative 728 + account 140 + add-listing 190 + gaps 80 = about
    1270. The container is 1110px from 1200 to 1439 - one row is impossible
    there whatever is done - and 93vw from 1440 up, where 1270 needs a 1366px
    window. Hence 1440, which is the theme's own container breakpoint rather
    than a number invented here.

    order 7 is after the add-listing button (order 5), so when it wraps it
    lands below a complete first row instead of splitting one.

    min-width is what makes the wrapping honest. The creative is a Revive
    <iframe width="728">: max-width cannot shrink it, only crop it, so the slot
    either has 728 or takes a line of its own. Without the floor it shrank to
    whatever was left and overflow:hidden ate the difference - the bug where
    narrowing the window sliced the right-hand end off the advert.
*/
.cat-header-banner {
    display: flex;
    justify-content: center;
    align-items: center;
    order: 7;
    flex: 0 0 100%;
    width: 100%;
    line-height: 0;
    min-width: min(728px, 100%);
    overflow: hidden;
}

@media (min-width: 1440px) {
    .cat-header-banner {
        order: 2; /* right after the categories row, where the keyword box was */
        flex: 1 1 728px;
        width: auto;
    }
}

/* For the day a creative arrives as a plain image rather than an iframe. */
.cat-header-banner img,
.cat-header-banner canvas {
    display: block;
    max-width: 100%;
    height: auto;
    margin: 0 auto;
}

/* The placeholder that stands in when no banner block is configured. */
.cat-header-banner .banner-space {
    min-height: 90px;
    width: 100%;
    border: 1px dashed var(--border-color, #ddd);
    border-radius: 8px;
    font-size: 12px;
    color: var(--date-color, #999);
}

/*
    From 1440 to 1520 the label is the difference between one row and two, so
    the categories control keeps its icon and drops its words: with the words
    the row wants about 1390px and needs a 1495px window, without them 1270 and
    1366. On a category page the reader is already inside a category and the
    filter bar sits just below. Delete this block to have the label back at
    every width - the layout still works, it just wraps sooner.
*/
@media (min-width: 1440px) and (max-width: 1520px) {
    .cat-header-row .category-menu__button {
        font-size: 0;
        gap: 0;
    }

    .cat-header-row .category-menu__button-icon {
        margin-right: 0;
    }
}

/* The panel. hidden until the button opens it, so it costs no space. */
.cat-header-search {
    order: 8;
    flex: 0 0 100%;
    width: 100%;
    padding-top: 12px;
}

.cat-header-search[hidden] {
    display: none;
}

/* Under the banner rather than over it: an overlay would cover the thing the
   advertiser is paying to have visible. */
@media (min-width: 1200px) {
    .cat-header-search {
        position: absolute;
        z-index: 30;
        top: 100%;
        left: 0;
        right: auto;
        width: 100%;
        max-width: 620px; /* a search field, not a banner-width bar */
        padding: 12px;
        border: 1px solid var(--border-color, #e0e0e0);
        border-radius: 10px;
        background: var(--block-bg, #fff);
        box-shadow: 0 8px 24px rgba(0, 0, 0, .12);
    }
}

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

/* ------------------------------------------------------------------
   The consolidated location filter's panel rows.

   The chip, the dropdown shell, the search box and the two buttons are
   all the filter plugin's own classes; only the tree inside is ours.
   See plugins/categoryFilter/location_filter.tpl.
   ------------------------------------------------------------------ */

.cf-loc-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 10px;
    font-size: 0.9em;
    cursor: pointer;
    border-radius: 6px;
}

/*
    EVERY ROW THAT CAN BE PICKED SHOWS THAT IT CAN BE PICKED.

    The checkbox was in the markup all along - what hid it is the template's
    global rule, which expects the old Flynax pattern of an input followed by a
    sibling <label> that draws a fake control:

        input[type="checkbox"]:not(.default) { opacity: 0; position: absolute; }

    These rows put the input INSIDE the label and have no such sibling, so
    nothing was ever drawn and a list of cities looked like a list of links.
    dropdown.css already undoes the same rule for .cf-dropdown-option; this is
    the same undoing for the location rows, so both surfaces show one control.

    Regions deliberately have no checkbox - they navigate, they do not filter -
    and that asymmetry is now legible instead of invisible: a box means it goes
    in the list, a chevron means it opens.
*/
.cf-loc-row input[type="checkbox"].cf-checkbox {
    position: static;
    opacity: 1;
    margin: 0;
    width: 15px;
    height: 15px;
    flex: 0 0 15px;
    -webkit-appearance: checkbox;
    -moz-appearance: checkbox;
    appearance: checkbox;
    accent-color: var(--noiz-light-orange, #FF8200);
    cursor: pointer;
}

.cf-loc-row:hover {
    background: rgba(255, 130, 0, .07);
}

/*
    The region is context; the city is the choice.

    Both rows used to be the same weight, with the city a shade smaller -
    which read as the region being the thing on offer. The region now sets
    itself back a size and the city takes the normal one, so the eye lands on
    what people actually pick.
*/
.cf-loc-row--state {
    font-size: 0.82em;
    color: var(--date-color, #777);
}

.cf-loc-row--city {
    margin-left: 14px;
}

.cf-loc-name {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.cf-loc-count {
    color: var(--date-color, #999);
    font-size: 0.92em;
    font-variant-numeric: tabular-nums;
}

/*
    A region row goes somewhere; a city row chooses something.

    The arrow used to be the only thing separating "look inside Attica" from
    "filter by Attica", on a row that did the second when you clicked it. Now
    the region row navigates - chevron on the right, no checkbox at all - and
    choosing a whole region is a row inside it.
*/
.cf-loc-nav {
    cursor: pointer;
}

/*
    The height is not decoration, it is what makes the chevron land straight.

    This span is empty, so as a flex item it computes to height 0 and
    align-items:center parks that zero-height box exactly on the row's centre
    line. The absolutely positioned ::after then measured its `top` down from
    that line rather than from a 16px box, putting the arrow 4px + half its own
    6px = 7px below the text on every row. Measured, not guessed: the box read
    `top 28.5 height 0.0` against a row centre of 28.5.

    With a real 16px box, (16 - 6) / 2 centres the arrow inside it.
*/
.cf-loc-go {
    width: 16px;
    height: 16px;
    flex: 0 0 16px;
    position: relative;
    opacity: .55;
}

.cf-loc-go::after {
    content: '';
    position: absolute;
    left: 3px;
    top: 5px;
    width: 6px;
    height: 6px;
    border-top: 2px solid currentColor;
    border-right: 2px solid currentColor;
    transform: rotate(45deg);
}

.cf-loc-nav:hover .cf-loc-go {
    opacity: 1;
}

/* Something is picked in there - a tick for the whole region, a number for
   cities - so a selection is never invisible from the level above. */
.cf-loc-badge {
    min-width: 18px;
    text-align: center;
    font-size: 0.78em;
    line-height: 18px;
    border-radius: 9px;
    color: #fff;
}

.cf-loc-badge.on {
    background: var(--noiz-light-orange, #FF8200);
}

.cf-loc-back {
    cursor: pointer;
    font-size: 0.85em;
    color: var(--noiz-dark-orange, #ee6820);
}

.cf-loc-back:hover {
    text-decoration: underline;
}

/* The region you are inside, as a heading rather than a choice. */
.cf-loc-here {
    border-top: none;
    margin-top: 0;
    color: var(--text-color, #333);
    font-size: 0.95em;
    text-transform: none;
    letter-spacing: 0;
}

.cf-loc-whole {
    font-weight: 600;
}

/* Which region a search result belongs to. */
.cf-loc-where {
    font-size: 0.8em;
    color: var(--date-color, #999);
    margin-right: 8px;
    white-space: nowrap;
}

.cf-loc-empty {
    padding: 14px 10px;
    color: var(--date-color, #999);
    text-align: center;
}

.cf-loc-other-head {
    margin-top: 8px;
    padding: 8px 10px 4px;
    font-size: 0.75em;
    font-weight: 600;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--date-color, #999);
    border-top: 1px solid var(--border-color, #eee);
}

#cf-location-body {
    max-height: 380px;
    overflow-y: auto;
    padding: 6px;
}

/* The location filter's pinned selection strip - see location-filter.js. */
.cf-loc-selected {
    padding: 4px 6px 10px;
    border-bottom: 1px solid var(--border-color, #eee);
    margin-bottom: 6px;
}

.cf-loc-selected-head {
    border-top: none;
    margin-top: 0;
    padding-top: 2px;
}

.cf-loc-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin: 3px 4px 0 0;
    padding: 4px 8px 4px 10px;
    border: 1px solid var(--noiz-light-orange, #FF8200);
    border-radius: 14px;
    font-size: 0.88em;
    background: rgba(255, 130, 0, .07);
}

.cf-loc-pill-x {
    cursor: pointer;
    font-weight: 700;
    line-height: 1;
    padding: 2px 3px;
    color: var(--noiz-dark-orange, #ee6820);
}

.cf-loc-pill-x:hover {
    color: #b44708;
}

/* A ticked row must survive being scrolled past. */
.cf-loc-row.on {
    background: rgba(255, 130, 0, .10);
    font-weight: 600;
}

/*
    The category page title, in the face the home page's section headings use.

    Both were measured off the live styles rather than guessed:

        category h1          Onest, 27.42px, 600, letter-spacing normal
        .section-lockup__title  Manrope, 800, -0.02em, line-height 1.15

    So the page title was set in a different family, three weights lighter and
    with none of the tightening - the home page and the category pages read as
    two different sites. This adopts the lockup's face, weight and tracking, and
    goes up in size because a page title outranks the section titles it is
    borrowing from: 36px against their 28.

    Manrope first with Onest behind it, exactly as the lockup does it - if the
    woff2 fails the heading lands on the site's own face rather than on whatever
    the OS offers.

    Scoped to body.category-header, which head.tpl puts on the listing_type
    controller and nothing else, so listing pages and static pages keep the h1
    they already had.

    Specificity note: the base rule is a bare `h1` at (0,0,1) and the phone
    override at 8017 of style.css is another bare `h1`, so this (0,2,1) beats
    both - including inside that media query, which is why the mobile size is
    restated here rather than inherited.
*/
body.category-header h1 {
    font-family: 'Manrope', 'Onest', sans-serif;
    font-size: 36px;
    /* 30px in style.css, which left the count floating a line away from the
       title it counts. Nothing else depends on this figure any more: Save
       Search used to sit on the title line and had to clear the same margin,
       and it has since moved down to the count itself. */
    margin-bottom: 8px;
    font-weight: 800;
    letter-spacing: -0.02em;
    line-height: 1.15;
    color: var(--body-font-color, #1a1a1a);
}

@media (max-width: 767px) {
    body.category-header h1 {
        font-size: 26px;
    }
}

/*
    The category title's own row, so Save Search can sit beside it.

    align-items: flex-end rather than center: the title is 36px and the button
    is ~36px tall, so centring them leaves the button floating against the
    title's cap height. Sitting them on a shared baseline-ish edge reads as one
    line rather than two objects that happen to be adjacent.

    The h1 keeps its own margin-bottom from style.css, so the row takes none -
    a margin here would double the gap above the results count.
*/
.page-title-row {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}

.page-title-row > h1 {
    /* The title takes the room it needs and the button keeps its own width;
       without this the flex item would refuse to wrap a long category name. */
    flex: 1 1 auto;
    min-width: 0;
}

/*
    Save Search sits on the count line now, not the title line.

    It is an action about the current result set, and the count is the
    sentence that describes that set - "2,423 Καταχωρίσεις" is exactly what
    saving the search would save. Beside the title it was next to the name of
    the category instead, which is not what gets saved.

    The old .page-title-row__save rule is gone with it; the class no longer
    exists in any template.
*/
.listings-count-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px;
}

.listings-count-row .listings-count {
    /* The count keeps whatever margin it had; the row must not add a second
       one underneath the button. */
    margin-bottom: 0;
}

.listings-count-row__save {
    /* Short label, fixed width, never squeezed. */
    flex: 0 0 auto;
}

/*
    On a phone the title needs the whole width, so the button drops beneath it
    and goes full width - a 36px title plus a button on one 390px line leaves
    the title two words per line.
*/
@media (max-width: 767px) {
    .page-title-row {
        align-items: stretch;
        gap: 0;
    }

    /* Save Search moved to the count line and no longer needs its
       full-width phone treatment here. The row itself keeps the rule: the
       browse toolbar now occupies that second line instead. */
    .listings-count-row__save {
        width: auto;
    }
}

/*
    Keep this button's label on a phone.

    `.navbar-btn span { display: none }` at 768px exists so the browse toolbar
    can collapse its buttons to icons when they are crammed against the view
    switcher and the sort control. This button no longer lives there - it has a
    full-width row of its own under the title - and stripped of its label it is
    a bookmark glyph alone, which tells a first-time reader nothing at all.

    Specificity, not source order: .navbar-btn span is (0,1,1) and so is
    .listings-count-row__save span, so an equal-weight rule would depend on
    which file happens to load last. Naming the parent makes it (0,2,1) and
    settles it. The breakpoint mirrors that rule's 768px rather than the
    767px used elsewhere here, so there is no single pixel of width where the
    button shows without its label.

    This followed the button from .page-title-row to the count line. Left
    behind it would have matched nothing, and .navbar-btn span would have
    quietly reduced Save Search to a bookmark glyph on every phone.
*/
@media (max-width: 768px) {
    .listings-count-row .listings-count-row__save span {
        display: inline;
    }
}

/*
    The listings count, as the title's subtitle rather than a stray line.

    `.listings-count` carries `padding: 0 15px`, which measured as a 15px indent
    from the h1's left edge AND a 15px gap on the right - the count sat inside
    its own narrower column while the title ran the full width above it. That
    padding is a phone-era gutter and the container already provides one here,
    so on category pages it goes and the line runs edge to edge with the title.

    14px was small enough to read as a caption under a 36px heading; 17px makes
    it the count of things the page is about.

    Scoped to body.category-header at (0,2,1) so search results and anywhere
    else drawing .listings-count keep the padding they were built with.
*/
body.category-header .listings-count {
    padding-left: 0;
    padding-right: 0;
    font-size: 17px;
}

/*
    ...but the container only provides that gutter on desktop.

    Below 767px the theme indents the h1 and the breadcrumb list by 15px
    themselves - measured across eleven widths, the switch is exactly at 767 -
    while the rule above went on zeroing the count at every width. So on a
    phone the count alone sat flush to the screen edge, 15px left of the title
    it belongs to, the chips and the cards.

    Restoring rather than narrowing the rule above: on desktop the padding
    genuinely is a leftover phone gutter, and there it should still go.
*/
@media (max-width: 767px) {
    body.category-header .listings-count {
        padding-left: 15px;
        padding-right: 15px;
    }
}

/*
    Lift the results up the page.

    Between the count and the first listing sat 258px of chrome carrying one
    40px toolbar and two rows of filter chips. Measured at 2000px wide, the
    stack was:

        count  -16- navbar(40) -20- [ 36 chips(98) 28 ] -20- listings

    The two 30-ish numbers are the loudest: .no-sidebar section.content_block
    gives every block 36px above and 28px below, which is right for the home
    page's stacked sections - they need air between one carousel and the next -
    and far too much for a strip of filter chips that belongs to the toolbar
    directly above it. The chips are not a section of the page; they are part of
    its header.

    Trimmed to:

        count  -10- navbar(40) -10- [ 8 chips(98) 10 ] -12- listings

    which is 70px less before anything a visitor came to see. Nothing here
    touches the home page: every rule is under body.category-header, and the
    block override names .filters-area as well, at (0,3,1) against the (0,2,1)
    it has to beat.
*/
body.category-header .listings-count {
    margin-bottom: 10px;
}

body.category-header .grid_navbar.listings-area {
    margin-bottom: 10px;
}

body.category-header .filters-area > section.content_block {
    padding-top: 8px;
    padding-bottom: 10px;
    margin-bottom: 0;
}

body.category-header .filters-area {
    margin-bottom: 12px;
}

/*
    "Select all (11)" above a set of search results.

    Reads as an action rather than an option: no checkbox, brand colour, and
    sitting above the rows it acts on. It carries .on when everything is already
    selected, at which point its own label has flipped to the opposite - the row
    is its own undo, so it should not also look like a thing that is switched on.
*/
.cf-loc-selectall {
    font-weight: 600;
    font-size: 0.85em;
    color: var(--noiz-dark-orange, #ee6820);
    border-bottom: 1px solid var(--border-color, #eee);
    margin-bottom: 4px;
    padding-bottom: 8px;
}

.cf-loc-selectall:hover {
    text-decoration: underline;
}

/*
    The consolidated panels get a ceiling and are allowed to wrap.

    .cf-dropdown-menu is width:auto with white-space:nowrap, which suits a short
    list of options and fails badly here: selecting forty-five Stratocasters put
    forty-five pills on one unwrappable line, and the panel grew past the edge
    of the screen with the list of models pushed out of sight below it.

    A ceiling in ch rather than px because the content is words - and 92vw so a
    phone is never handed a panel wider than itself.
*/
#cf-dropdown-location,
#cf-dropdown-brand {
    max-width: min(46ch, 92vw);
}

/* The pills wrap; everything else in the panel keeps the menu's nowrap. */
.cf-loc-selected {
    white-space: normal;
    /* Even capped at twelve, long model names run to several lines - so the
       strip scrolls rather than pushing the list off the bottom. */
    max-height: 108px;
    overflow-y: auto;
}

.cf-loc-pill-more {
    cursor: pointer;
    font-weight: 600;
    border-style: dashed;
}

.cf-loc-pill-more:hover {
    background: rgba(255, 130, 0, .16);
}

/*
    The control that unfolds the rest of the list.

    Reads as an action rather than an option - no checkbox, brand colour, its
    +/− carrying the state - and sits at the end of what it is hiding, which is
    where somebody who has run out of rows is already looking.
*/
/*
    Matched to .cf-mobile-show-more rather than styled fresh: the vendor's own
    "+ Περισσότερα" sits directly beneath this one in the same panel, on the
    next filter section, and two treatments of one control read as two
    different things. 14px / 500 / #222, as that rule declares.
*/
.cf-loc-more {
    font-size: 14px;
    font-weight: 500;
    color: var(--body-font-color, #222);
    border-top: 1px solid var(--border-color, #eee);
    margin-top: 4px;
    padding-top: 10px;
}

.cf-loc-more:hover {
    text-decoration: underline;
}

.cf-loc-more-icon {
    display: inline-block;
    width: 14px;
    font-weight: 700;
}

/*
    The filter panel's section headings.

    22px is a page-title size, and there are eleven of them stacked - Κατηγορία,
    Μάρκα, Χαρακτηριστικά, Σώμα, Χορδές, Χέρι, Τιμή, Τοποθεσία, Χώρα κατασκευής,
    Ανταλλαγή - so the panel read as eleven headlines rather than a list you can
    run your eye down. 17px keeps them clearly titles while letting more than
    six fit on a phone screen at once.
*/
/*
    Specificity, not order: mobile.css declares .cf-mobile-section-title at
    (0,1,0) and is emitted by box.tpl inside the body, so it loads AFTER
    custom.css and wins any tie. Naming the section makes it (0,2,0). This
    was 22px on the page while the rule below said 17 - measured, not assumed.
*/
.cf-mobile-section .cf-mobile-section-title {
    font-size: 17px;
}

/* The row shrinks with the text it holds. */
.cf-mobile-section .cf-mobile-section-header {
    padding-top: 14px;
    padding-bottom: 14px;
}

/*
    Subcategories drawn as what they are: branches under the category above them.

    Ηλεκτρικές, Ακουστικές, Ηλεκτροακουστικές and Κλασικές sat flush left,
    directly beneath the highlighted "Κιθάρες", reading as four more categories
    at the same level rather than four kinds of guitar. An indent and a spine
    say the relationship the markup already knew.

    Scoped to .cf-cat-children, which the template puts ONLY on the list below
    the current category. The sibling list further down carries the same
    data-filter-key and is NOT below anything - indenting it too would state a
    relationship that does not exist.
*/
.cf-category-section .cf-cat-children {
    margin-left: 8px;
    padding-left: 16px;
    border-left: 1px solid var(--border-color, #e6e6e6);
}

/*
    The little arm from spine to row. Positioned on the row rather than drawn
    into the border so it lands on the text's centre line whatever the row's
    height - a two-line category name keeps its arm beside the first line.
*/
.cf-category-section .cf-cat-children .cf-mobile-option {
    position: relative;
}

.cf-category-section .cf-cat-children .cf-mobile-option::before {
    content: '';
    position: absolute;
    left: -16px;
    top: 18px;
    width: 10px;
    height: 1px;
    background: var(--border-color, #e6e6e6);
}

/* The spine should stop at the last child, not run past it into open space. */
.cf-category-section .cf-cat-children .cf-mobile-option:last-child {
    border-bottom: none;
}

/*
    The actions menu on /my-ads/, named rather than drawn as three dots.

    style.css sizes .menu-trigger as a 40x40 icon square, which is right for a
    glyph and wrong for a word, so this widens it and gives it a border - the
    dots read as decoration, and the one action the site most needs people to
    take ("Σήμανση ως πουλημένο") was inside them.

    Higher specificity than the (0,2,0) rule it overrides, because style.css
    loads after custom.css.
*/
.my-listing-card__menu .menu-trigger.menu-trigger--labelled {
    width: auto;
    height: auto;
    gap: 6px;
    padding: 8px 12px;
    border: 1px solid var(--border-color, #d8d8d8);
    border-radius: 8px;
    font-size: 14px;
    font-weight: 500;
    color: var(--body-font-color, #374151);
    white-space: nowrap;
}

.my-listing-card__menu .menu-trigger.menu-trigger--labelled:hover {
    border-color: var(--noiz-light-orange, #FF8200);
    background: rgba(255, 130, 0, .06);
}

.menu-trigger__caret {
    flex-shrink: 0;
    opacity: .6;
}

/* On a narrow card the word is what matters; the caret can go. */
@media (max-width: 480px) {
    .my-listing-card__menu .menu-trigger.menu-trigger--labelled {
        padding: 7px 10px;
    }

    .menu-trigger__caret {
        display: none;
    }
}

/*
    "Πουλήθηκε" on the listing's own page.

    A sold listing no longer appears in browse or search, but its page is still
    reachable by link, and until now it looked identical to one still for sale.
    Stock says this with a watermark stamped on the photo, and files/watermark/
    holds sold_en.png only - so for Greek, the default language, nothing was
    drawn at all.

    Solid rather than outlined, unlike the condition tag beside it: this is a
    statement about whether the thing can be bought, not another attribute of it.
*/
.listing-header__sold {
    display: inline-flex;
    align-items: center;
    padding: 5px 12px;
    border-radius: 7px;
    /* --sold-badge-*, not --body-font-color: that one is the page text
       colour and flips with the theme, so using it as a background made
       this pale-on-pale in dark mode. Declared in light.css and dark.css. */
    background-color: #15803D;
    color: #FFFFFF;
    font-size: 0.85em;
    font-weight: 700;
    letter-spacing: .02em;
    text-transform: uppercase;
}

/*
    "Πουλήθηκε" on a listing card.

    Deliberately NOT modelled on .featured-badge / .new-badge next to it: both of
    those default to display:none and are switched back on only inside
    `section#listings article.item`, so they draw on browse and nowhere else.
    Browse is the one place a sold listing no longer appears - the card is drawn
    in favourites, in a seller's other listings, in the similar-listings row -
    so a badge that only works on browse would be a badge that never works.

    Solid dark, the same weight as the badge on the listing's own page, and
    heavier than the grey Featured pill: this is not another attribute of the
    thing, it is whether the thing can be bought.
*/
article.item ul.card-info li.sold-badge {
    display: block;
    margin-bottom: 8px;
}
article.item ul.card-info li.sold-badge span {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    border-radius: 5px;
    /* --sold-badge-*, not --body-font-color: that one is the page text
       colour and flips with the theme, so using it as a background made
       this pale-on-pale in dark mode. Declared in light.css and dark.css. */
    background-color: #15803D;
    color: #FFFFFF;
    font-size: 0.7em;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .5px;
}

/*
    A sold listing on /my-ads/, said at card level rather than in a pill.

    The only mark was a pale red pill among four or five other badges
    (background #fee2e2, text #991b1b) - easy to miss when scanning a list of
    listings, and red reads as something gone wrong rather than something
    achieved. A seller scanning /my-ads/ should be able to see which things are
    done without reading any of the badges.

    So the whole card steps back: the photo desaturates and dims, and the badge
    goes solid dark to match the one on the listing's own page and on the public
    card. Same visual language in all three places, so "Πουλήθηκε" looks the
    same wherever a seller meets it.

    Deliberately not greying the text or the actions. The listing is finished,
    not disabled - «Ενέργειες» still has to be reachable, because undoing a
    mis-click is exactly what someone who notices this badge wants to do.
*/
.my-listing-card--sold .my-listing-card__image img {
    filter: grayscale(1);
    opacity: .55;
}
.my-listing-card--sold .my-listing-card__image::after {
    content: '';
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, .04);
    pointer-events: none;
}
/*
    No border override for a sold card.

    It used to darken the border to mark the card out. custom.css loads
    after both theme files, so that one line also beat dark.css's own
    border colour and gave sold cards a different edge from every other
    card in dark mode. The desaturated photo and the badge already say it;
    the border was the least of the three and the only one that fought the
    theme.
*/

/* The badge itself: same weight as the public one, and no longer an error. */
/*
    ONE FIXED COLOUR, AND NO VARIABLE.

    Two attempts failed here and both failed the same way - the label
    became invisible against its own badge - so this stops trying to be
    clever about the theme.

    Attempt 1 used var(--body-font-color) as the BACKGROUND. That variable
    is the page's text colour and flips with the theme (#111 light,
    #DADADA dark), so in dark mode the badge went pale and the white label
    vanished into it.

    Attempt 2 declared --sold-badge-bg/-fg in light.css and dark.css - the
    only hook available, since the switcher disables a whole stylesheet
    rather than setting a class. Correct in every combination I could
    reproduce, and still wrong on the reporter's screen: a black pill with
    neither the tick nor the word visible, which needs the foreground AND
    the background to resolve dark at the same time. Two stylesheets that
    disagree - one cached, one fresh, behind Cloudflare on stage - will do
    that, and nothing in this file can prevent it.

    So: a literal colour pair, resolved by no one. #15803D carries white
    text at 5.02:1 - AA for normal text, and this label is bold - while
    still holding 3.76:1 against a #111 card, so the pill reads on a white
    background and a dark one alike. There is no theme left to get wrong.

    Green, not the red a sold stamp conventionally uses. A sale is the
    outcome this site exists for; red is the colour of everything that has
    gone wrong elsewhere in the interface, and the old pale-red pill was
    already being read that way. Measured across seven candidate greens -
    #15803D was the one that keeps an accessible label without vanishing
    into a dark card (#146C43 reads better on white, 6.45:1, but drops to
    2.93:1 against #111).

    If this ever needs to differ per theme again, put the whole rule in
    light.css and dark.css - not a variable read from a third file.
*/
/*
    !important on the foreground, and it is not laziness.

    The badge took its GREEN from the block below and its text colour from
    somewhere else - on the same element, in the same cascade. That is only
    possible if a later or more specific declaration sets `color` alone, and
    I could not find it: the file stage serves declares background-color and
    color together, and none of the twelve stylesheets the page loads has a
    another `color` on any selector that can match this element. Whatever it
    is - a plugin sheet added on the logged-in page, an extension, an inline
    style - it is outside what I can read from here.

    So the two properties that decide whether the label is legible are
    forced, and only those two. Everything else stays overridable. The
    selector is also lifted to three classes so it wins on specificity
    against anything at (0,2,0) even where !important is stripped.

    The tick gets a literal white rather than currentColor: if `color` is
    ever beaten again, the icon should not follow it into invisibility.
*/
.my-listing-card .my-listing-card__badges .badge--sold,
.my-listing-card--sold .my-listing-card__badges .badge--sold,
.my-listing-card .badge--sold,
.my-listing-card--sold .badge--sold {
    background-color: #15803D !important;
    color: #FFFFFF !important;
    font-weight: 700;
    letter-spacing: .3px;
    text-transform: uppercase;
}
.my-listing-card .my-listing-card__badges .badge--sold svg,
.my-listing-card .badge--sold svg {
    stroke: #FFFFFF !important;
}

/*
    Καθαρισμός φίλτρων keeps the button it has always had.

    It used to be drawn twice: categoryFilter's plain text link at the end of the
    chip row, and a styled copy in the toolbar. The toolbar copy is the one people
    saw, so that is the design - a pale pill with the brand orange and a cross -
    and removing it must not turn the survivor back into a bare link.

    These are the production values, read off #navbar-clear-filters rather than
    guessed: background #fff5f5, colour #FF8200, 1px transparent border, radius
    8px, padding 8px 14px, 14px/500, 6px gap, 16x16 icon. Note the colour is NOT
    light.css's .navbar-btn-clear red (#d9534f) - something overrides it to brand
    orange, and orange is what shipped, so orange is what this matches.

    a.cf-clear-all, not .cf-clear-all: the plugin's own dropdown.css styles it as
    a text link at (0,2,0) and loads after this file, so the element selector is
    what wins.
*/
.cf-filters-row a.cf-clear-all {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 14px;
    border: 1px solid transparent;
    border-radius: 8px;
    background: #fff5f5;
    color: #FF8200;
    font-size: 14px;
    font-weight: 500;
    /* No line-height: .navbar-btn did not set one either, and adding 1.2 made
       the button 35px tall against production's 34. */
    text-decoration: none;
    white-space: nowrap;
    transition: all .2s ease;
}

.cf-filters-row a.cf-clear-all:hover {
    background: #ffe9e3;
    border-color: #FF8200;
    text-decoration: none;
}

.cf-filters-row a.cf-clear-all svg {
    flex-shrink: 0;
}

/*
    The filter chips, in colours that follow the theme.

    dropdown.css builds this whole row out of literals - `border: 1px solid
    #222`, `background: #fff`, `.has-selection` filled #222 with #fff text - so
    it only ever made sense on a white page. On the dark theme it was a row of
    white pills glaring off a near-black background, which is what this fixes.
    The first version of this rule was my own #fafafa on #e3e3e3, which was the
    same mistake in a quieter shade: a literal cannot follow a theme.

    Every value is now a token that light.css and dark.css both define, which is
    the only way to be right in both from one rule - the two sheets are mutually
    exclusive and one of them is always disabled, so custom.css cannot write a
    per-theme colour.

        surface  --menu-active-bg          #F5F5F5 light · #222 dark
        line     --highlight-border-color  #d4d4d4 light · #4D4D4D dark
        text     --body-font-color         #111    light · #DADADA dark

    #222 against the #111 page is the "slightly lighter than the background"
    Alex asked for, and on white it stays the faint grey the chips already had.

    The selected chip is restated further down in the brand orange. It has to be
    restated at all because with the unselected chips now at #222 in dark, the
    plugin's own #222 fill for the selected one would have hidden it among its
    neighbours.

    Specificity: dropdown.css loads after custom.css, so each rule carries one
    class more than the plugin's - .cf-filters-row for the toggles, and the
    extra .has-selection for the selected state.
*/
.cf-filters-row .cf-dropdown-toggle,
.cf-filters-row .cf-all-filters-btn {
    border-color: var(--highlight-border-color, #d4d4d4);
    background: var(--menu-active-bg, #f5f5f5);
    color: var(--body-font-color, #111);
}

/*
    Hover moves the line, not the fill. A second background shade would need a
    third token that does not exist in both sheets; the border going to the text
    colour reads as "this is live" in either theme.
*/
.cf-filters-row .cf-dropdown-toggle:hover,
.cf-filters-row .cf-all-filters-btn:hover {
    border-color: var(--body-font-color, #111);
    background: var(--menu-active-bg, #f5f5f5);
}

/*
    The chosen filter is the brand orange.

    It was an inverted pill - the text colour as a fill - which stood out but
    said nothing; it read as "a chip, but backwards". Orange is what this site
    already uses to mean active, on the sell button, the current tab in the
    bottom bar and every primary control, so a filter that is doing something
    now says so in the same language.

    --noiz-light-orange is one of the few tokens that is the SAME in both
    sheets (#FF8200), which is what makes this one declaration rather than a
    per-theme pair, and white on it follows every other orange control here
    through --button-text-color.

    Hover deepens to --noiz-dark-orange instead of fading opacity: a
    translucent chip picks up whatever is behind it, and behind this one is a
    page that changes colour with the theme.
*/
.cf-filters-row .cf-dropdown-toggle.has-selection {
    border-color: var(--noiz-light-orange, #FF8200);
    background: var(--noiz-light-orange, #FF8200);
    color: var(--button-text-color, #fff);
}

.cf-filters-row .cf-dropdown-toggle.has-selection:hover {
    border-color: var(--noiz-dark-orange, #ee6820);
    background: var(--noiz-dark-orange, #ee6820);
}

/*
    The label carries its own colour, so recolouring the chip is not enough.

    dropdown.css sets `.cf-dropdown-label { color: #222 }` and, for the selected
    chip, `#fff`. Against the new fills that is invisible twice over: #222 text
    on a #222 chip in dark mode, and white text on the light selected chip. The
    row rendered as a set of empty pills with nothing but a chevron in them -
    which the chip-level colours alone reported as fine, because the toggle
    itself was the right colour all along.

    Same two tokens as the chip, so the label always resolves to the opposite of
    whatever it sits on.
*/
.cf-filters-row .cf-dropdown-label {
    color: var(--body-font-color, #111);
}

.cf-filters-row .cf-dropdown-toggle.has-selection .cf-dropdown-label {
    color: var(--button-text-color, #fff);
}

/*
    Όλα τα Φίλτρα, the same size as the chips beside it.

    It was 42px against their 38 - padding of 10px 20px where the chips use
    8px 16px - which read as a misalignment rather than as emphasis, because
    nothing else about it is emphasised. min-height matches the chips' own so the
    two cannot drift apart if one is edited later.

    Its own greys stay: it opens the whole panel rather than filtering one field,
    and a slightly firmer fill is a fair way to say so at the head of the row.
*/
.cf-filters-row .cf-all-filters-btn {
    padding: 8px 16px;
    min-height: 38px;
}

/*
    The hold banner, for a seller whose email we cannot reach.

    Not the .noiz-notice toast: that is transient, dismissible and lives at the
    bottom of the viewport. This is a state, not an event - it stays until the
    address is fixed, so it sits at the top of the content where it is read
    before anything else, and it has no close button because closing it would
    not bring the listings back.

    Amber rather than red. Their listings are hidden and that is serious, but
    nothing is lost and one edit undoes it; red is for damage.

    Fixed colours, not theme variables - the same reasoning as the sold badge.
    #7a4a00 on #fff8e6 is 7.2:1, and both hold up on a dark page because neither
    is drawn from a palette that flips.
*/
.bounce-hold {
    display: flex;
    align-items: center;
    gap: 12px;
    margin: 0 0 20px;
    padding: 14px 18px;
    border: 1px solid #f0c36d;
    border-radius: 10px;
    background: #fff8e6;
    color: #7a4a00;
}

.bounce-hold__icon {
    flex: 0 0 22px;
    width: 22px;
    height: 22px;
}

.bounce-hold__body {
    display: flex;
    flex-direction: column;
    gap: 2px;
    flex: 1 1 auto;
    min-width: 0;
}

.bounce-hold__title {
    font-size: 15px;
    font-weight: 700;
}

.bounce-hold__text {
    font-size: 14px;
    line-height: 1.45;
}

.bounce-hold__action {
    flex: 0 0 auto;
    padding: 9px 16px;
    border-radius: 8px;
    background: #7a4a00;
    color: #fff;
    font-size: 14px;
    font-weight: 600;
    text-decoration: none;
    white-space: nowrap;
}

.bounce-hold__action:hover {
    background: #613a00;
    color: #fff;
    text-decoration: none;
}

@media (max-width: 640px) {
    .bounce-hold {
        flex-wrap: wrap;
    }

    .bounce-hold__action {
        width: 100%;
        text-align: center;
    }
}

/*
    The current page, last in the breadcrumb trail.

    bread_crumbs.tpl now prints it as a plain <li> rather than skipping it, so
    /guitars/ says "Noiz / Κιθάρες & Μπάσα / Κιθάρες" instead of stopping one
    short. It is deliberately not a link - it goes nowhere - so it gets the
    text colour at full strength while the links behind it sit at 0.8, which is
    what makes "you are here" legible without adding a weight or a colour.
*/
#bread_crumbs li.bread-crumbs__current {
    color: var(--body-font-color);
}

/*
    Close the gap between the filter chips and the first row of cards.

    It was 50px, and none of it was deliberate - three separate blocks each
    contributing their own bottom spacing:

        section.content_block:not(.no-style) > div   28px  (style.css, sitewide)
        section.content_block                        10px  padding-bottom
        aside.filters-area                           12px  margin-bottom

    The 28px is the sitewide content-block rule and every other block on the
    site wants it, so it is overridden here only for the filter block rather
    than edited at source. That leaves 22px, plus the row's own 15px of inner
    padding - close enough to read as one group with the grid it filters.

    Specificity ties with the style.css rule (two elements, two classes) and
    wins on order. categoryFilter's own stylesheet loads after custom.css but
    sets nothing here.
*/
section.content_block.categoryFilter > div {
    padding-bottom: 0;
}

/*
    Logo, categories and search share the logo's row on a phone.

    header.tpl marks this wrapper `flex-column-reverse flex-md-row`, so below
    768 it became a vertical stack: the search icon on one line, "Όλες οι
    κατηγορίες" on the next, the pair of them 104px tall beside a 57px logo.
    That is what pushed the header to 218px before any content - two rows of
    chrome to carry two controls that fit on one.

    Measured at 390: logo 52 + gap 16 + button 183 + gap 16 + icon 42, plus the
    container's 15px either side, comes to 339 of 390. It fits, and the account
    links keep the line below them that they already wrapped onto.

    !important because flex-column-reverse is a Bootstrap utility and carries
    its own. 767.98 rather than 767 to match where flex-md-row takes over,
    leaving no width served by neither rule.
*/
@media (max-width: 767.98px) {
    .cat-header-row {
        flex-direction: row !important;
    }
}

/*
    Below 340 the label is the difference between fitting and being clipped.

    The row ends at 324 and the container wants 15 after it, so it needs 339px
    of window. At 320 the search icon ran to 324 and an ancestor's
    overflow:hidden ate the last 4px - not a scrollbar, which is why the page
    still measured scrollWidth == innerWidth and looked fine by that test.

    Same treatment the 1440-1520 squeeze uses: the words go, the icon stays.
    The reader is already inside a category here.
*/
@media (max-width: 339.98px) {
    .cat-header-row .category-menu__button {
        font-size: 0;
        gap: 0;
    }

    .cat-header-row .category-menu__button-icon {
        margin-right: 0;
    }
}

/*
    No list control on a phone, because a phone no longer honours it.

    grid.tpl forces the grid below 768; leaving the icon visible would offer a
    switch that does nothing and, worse, show as active while the page renders
    as a grid. Gallery and map remain, which is the pair that behaves.

    Same breakpoint as the flip. The desktop toolbar keeps all three.
*/
@media (max-width: 767.98px) {
    .grid_navbar .switcher .buttons .list {
        display: none;
    }
}

/* =============================================
   MOBILE BOTTOM NAVIGATION
   ============================================= */

/*
    Five tabs fixed to the bottom of a phone screen.

    Hidden by default and shown only below 768, rather than the reverse: a rule
    that has to be switched off for every desktop page is a rule that will one
    day be on for one of them.

    z-index 900 puts it over page content and under the modal mask at 10000 -
    the login popup this bar can open has to cover it, not sit behind it.

    Colours come from the theme variables both light.css and dark.css define,
    so the bar follows the theme from one rule set. The two sheets are mutually
    exclusive - one is disabled outright - so a literal here could only ever be
    right in one of them.
*/
/*
    The bar's height, named once because two rules need to agree on it: the
    bar itself and the padding that stops it covering the end of the page.
    They were 62 and 58 on the first pass, and the last 4px of the footer sat
    underneath. Stable across the eight languages because the labels are
    nowrap with an ellipsis, so no translation can add a line.
*/
:root {
    --mobile-nav-h: 62px;
}

.mobile-nav {
    display: none;
    min-height: var(--mobile-nav-h);
    position: fixed;
    z-index: 900;
    right: 0;
    bottom: 0;
    left: 0;
    background: var(--content-background-color, #fff);
    border-top: 1px solid var(--highlight-border-color, #d4d4d4);

    /*
        The home indicator on a modern iPhone sits in the bottom ~34px. Without
        the inset the last row of tabs is under it and the taps land on the
        system gesture instead.
    */
    padding-bottom: env(safe-area-inset-bottom, 0px);
}

@media (max-width: 767.98px) {
    .mobile-nav {
        display: flex;
        align-items: stretch;
    }

    /*
        Room at the end of the page for the bar to stand on. Without it the bar
        covers the last of the footer, and on short pages the final link is
        unreachable.
    */
    body {
        padding-bottom: calc(var(--mobile-nav-h) + env(safe-area-inset-bottom, 0px));
    }
}

.mobile-nav__item {
    display: flex;
    flex: 1 1 0;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    min-width: 0;
    padding: 7px 2px 6px;

    /* 44px is the smallest thing a thumb hits reliably. */
    min-height: 44px;

    border: 0;
    background: none;
    color: var(--cat-link-color, #777);
    font-size: 10px;
    line-height: 1.2;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
}

.mobile-nav__item:hover,
.mobile-nav__item:focus-visible {
    color: var(--noiz-light-orange, #FF8200);
    text-decoration: none;
}

.mobile-nav__item.is-active {
    color: var(--noiz-light-orange, #FF8200);
}

/*
    Stroked, like every other icon in this header family. These paths carry no
    fill and no stroke of their own, so both are set here - given a fill they
    render as filled blobs, which is what the search icon did when it shipped
    that way.
*/
.mobile-nav__icon {
    width: 22px;
    height: 22px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    flex: none;
}

/*
    The label has one line and no more. "Νέα καταχώριση" and "Αγαπημένα" are
    long next to a 10px tab, and a wrap makes that one tab taller than the
    other four.
*/
.mobile-nav__label {
    max-width: 100%;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

/* Selling is the one tab drawn as a button. */
.mobile-nav__fab {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 26px;
    border-radius: 8px;
    background: var(--noiz-light-orange, #FF8200);
    color: #fff;
}

.mobile-nav__item--primary {
    color: var(--noiz-light-orange, #FF8200);
}

.mobile-nav__item--primary .mobile-nav__icon {
    width: 18px;
    height: 18px;
    stroke-width: 2.2;
}

/* Unread messages, carried up from the account page they live on. */
.mobile-nav__icon-wrap {
    position: relative;
    display: inline-flex;
}

.mobile-nav__icon-wrap.has-badge::after {
    content: '';
    position: absolute;
    top: -1px;
    right: -2px;
    width: 8px;
    height: 8px;
    border: 2px solid var(--content-background-color, #fff);
    border-radius: 50%;
    background: var(--noiz-light-orange, #FF8200);
}

/*
    The tab labels take the size and face they were given.

    Both were being lost, in different directions and only visible in the
    browser:

      - The four <a> tabs rendered at 16px, not the 10px set on .mobile-nav__item
        - a theme link rule outranks a font-size inherited from the parent, so
        Αναζήτηση and Αγαπημένα truncated inside a 74px tab that had room for
        them at the intended size.
      - The logged-out tab is a <button>, and a button does not inherit
        font-family from the page: it came out in Arial while its four
        neighbours were in Onest. The same mismatch the listings count had, from
        a different cause.

    Set on the label itself, and the family explicitly to inherit, so neither
    can drift again.
*/
.mobile-nav .mobile-nav__item,
.mobile-nav .mobile-nav__label {
    font-family: inherit;
    font-size: 10px;
    line-height: 1.2;
}

/*
    One point smaller on the narrowest phones.

    At 320 a tab is 64px wide and "Λογαριασμός" wants 63 of it before padding -
    it was the single label, in the single language, that clipped. German
    ("Verkaufen") and Bulgarian ("Търсене") both fit at 320; Greek is simply the
    longest here, which is easy to miss testing in English, and the browser
    reports English unless the language cookie is set.

    9px keeps it whole with room to spare rather than shortening the word: a
    tab that reads "Λογαρια..." is worse than one a point smaller.
*/
@media (max-width: 359.98px) {
    .mobile-nav .mobile-nav__item,
    .mobile-nav .mobile-nav__label {
        font-size: 9px;
    }
}

/*
    Inactive tabs are grey; only the current one is orange.

    Third thing on this bar a theme rule quietly took over, after the size and
    the face: links inherit --link-color, which IS the brand orange, so every
    tab rendered as though it were the active one and the active state said
    nothing. The logged-out tab is a <button> and kept the grey, so four tabs
    were orange and the fifth was not - visibly wrong in a way the markup does
    not suggest.

    Element + two classes, so it outranks whatever link rule was winning, and
    is-active repeats at the same weight below to take the colour back.
*/
.mobile-nav a.mobile-nav__item,
.mobile-nav button.mobile-nav__item {
    color: var(--cat-link-color, #777);
}

.mobile-nav a.mobile-nav__item:hover,
.mobile-nav a.mobile-nav__item:focus-visible,
.mobile-nav button.mobile-nav__item:hover,
.mobile-nav button.mobile-nav__item:focus-visible,
.mobile-nav a.mobile-nav__item.is-active,
.mobile-nav a.mobile-nav__item--primary {
    color: var(--noiz-light-orange, #FF8200);
}

/*
    The unread count on the messages tab.

    Red rather than the brand orange: orange is what this bar uses for "you are
    here" and for the sell button, so an orange bubble would read as another
    piece of chrome. A count of unread messages is the one thing here that is
    news.

    Always rendered, hidden at zero through .is-empty, so the poll that keeps it
    current has an element to write into and toggle rather than having to build
    one and get its markup right in two places.

    The ring is the bar's own background, not white: in dark mode a white ring
    around a red disc is a bright halo on a near-black bar.
*/
.mobile-nav__badge {
    position: absolute;
    top: -5px;
    left: 11px;
    min-width: 16px;
    height: 16px;
    padding: 0 4px;
    box-sizing: border-box;
    border: 2px solid var(--content-background-color, #fff);
    border-radius: 8px;
    background: #DC2626;
    color: #fff;
    font-size: 9px;
    font-weight: 700;
    line-height: 12px;
    text-align: center;
    white-space: nowrap;
}

.mobile-nav__badge.is-empty {
    display: none;
}

/* =============================================
   MOBILE BOTTOM NAVIGATION - ACCOUNT MENU
   ============================================= */

/*
    The avatar in the account tab.

    avatar_with_initials.tpl draws either an <img> or a coloured disc with an
    initial, and both need forcing to the tab's icon size - the component sizes
    itself from .header-avatar in the header and .udm-avatar in the menu, and
    inherits neither here.
*/
/*
    Match what the component actually emits.

    avatar_with_initials.tpl renders <img class="avatar-image"> for a photo and
    <div class="avatar-initials avatar-small"> for the fallback - a div, not the
    span these rules first named. So the photo was being sized and the initials
    disc was not: it kept its own 32px inside a 28px wrapper and spilled out.
*/
.mobile-nav__avatar,
.mobile-nav__avatar .avatar-image,
.mobile-nav__avatar .avatar-initials {
    width: 22px;
    height: 22px;
    min-width: 22px;
    border-radius: 50%;
    overflow: hidden;
    font-size: 10px;
    line-height: 22px;
}

.mobile-nav__avatar .avatar-image {
    display: block;
    object-fit: cover;
}

/*
    The initials disc centres its letter itself; these override the component's
    own 32px sizing without touching how it looks anywhere else.
*/
.mobile-nav__avatar .avatar-initials {
    display: flex;
    align-items: center;
    justify-content: center;
}

/*
    A photograph cannot go orange to say "open", so the ring does it. Drawn with
    box-shadow rather than a border so the avatar keeps its 22px and the tabs
    stay on one baseline.
*/
.mobile-nav__item--account.is-active .mobile-nav__avatar {
    box-shadow: 0 0 0 2px var(--noiz-light-orange, #FF8200);
}

/*
    Under the bar, over everything else.

    At 940 the scrim covered the bar as well, which dimmed the avatar that
    had just been tapped and greyed out the four tabs beside it. 890 puts it
    beneath the bar (900) and above the page: content dims, the bar stays
    live, and the open menu at 950 sits over both.
*/
.mobile-nav__scrim {
    /*
        Hidden everywhere by default, shown only inside the phone breakpoint.

        The open/close script runs at every width - it follows the same
        circle_opened class the desktop header toggles - so with only the
        [hidden] attribute deciding this, opening the account menu on a
        DESKTOP dimmed the whole page. Caught by checking the desktop after
        the mobile work looked finished.
    */
    display: none;
    position: fixed;
    z-index: 890;
    inset: 0;
    background: rgba(0, 0, 0, .45);
}

@media (max-width: 767.98px) {
    /*
        The header's avatar goes; this bar has it.

        Only the trigger, never #user-navbar itself - the panel we are about to
        re-anchor is inside it, and hiding the parent would hide the menu we
        are trying to show.
    */
    #user-navbar > .default {
        display: none;
    }

    /*
        The desktop dropdown, re-anchored as a drop-up.

        Nothing between this panel and <body> carries a transform, filter or
        paint containment - checked in the browser - so position:fixed resolves
        against the viewport and the panel can sit above the bar while its
        markup stays where the header put it. That is what lets one panel serve
        both layouts instead of a mobile copy that drifts.

        It has to be re-anchored, not merely restyled: header.page-header is
        position:static, so left alone the panel opens at the top of the
        DOCUMENT - off-screen for anyone who has scrolled.

        Scoped to .circle_opened so the closed state stays exactly as the theme
        left it, display:none included.
    */
    /*
        The host has to clear the scrim, not just the panel.

        lib.js calls flUtil.setPriorityZIndex on open, which writes an INLINE
        z-index onto #user-navbar - a number derived from the other
        .priority-z-index elements, so a small one. On a positioned element
        that makes a stacking context, and everything inside it is then
        confined to that number: the panel asking for 950 was still painted
        beneath a scrim at 940, because 950 only ranks it against its
        siblings. Filling the scrim with solid red was what showed it - the
        whole screen went red, panel included.

        !important because the value it is beating is inline. Only while
        open, so the header keeps its own stacking on every other page state.
    */
    #user-navbar.circle_opened {
        z-index: 950 !important;
    }

    #user-navbar.circle_opened > .content.a-menu {
        position: fixed;
        z-index: 950;

        /*
            top:auto matters. The theme positions this panel absolutely and
            sets a top; leaving it in place while adding a bottom pins both
            edges, and the box is then stretched between a top of 700px and a
            bottom of 62px in a 700px viewport - which resolves to 2px of
            border and no menu. It looked like the panel had not opened.
        */
        top: auto;
        right: 0;
        bottom: calc(var(--mobile-nav-h) + env(safe-area-inset-bottom, 0px));
        left: 0;
        width: auto;
        max-width: none;
        margin: 0;
        border-radius: 14px 14px 0 0;

        /*
            The panel is 765px of links on a 700px phone, so it scrolls.

            dvh, with vh underneath for anything that does not know it: the
            visible viewport shrinks and grows as mobile browser chrome comes
            and goes, and vh alone is the taller of the two - which would put
            the end of the menu under the address bar.
        */
        max-height: calc(100vh - var(--mobile-nav-h) - 24px);
        max-height: calc(100dvh - var(--mobile-nav-h) - 24px);
        overflow-y: auto;
        overscroll-behavior: contain;
    }

    .mobile-nav__scrim:not([hidden]) {
        display: block;
    }

    /* The page underneath stays put while the panel is open. */
    body.has-nav-menu-open {
        overflow: hidden;
    }
}

/*
    The avatar tab carries no label, so it gets the room the label would have.

    28px rather than the 22px the icon tabs use: alone in its column it can
    afford to be the size a face needs to be recognisable, and it lines up with
    the icons above their labels rather than floating.
*/
.mobile-nav__item--account {
    justify-content: center;
}

.mobile-nav__item--account .mobile-nav__avatar,
.mobile-nav__item--account .mobile-nav__avatar .avatar-image,
.mobile-nav__item--account .mobile-nav__avatar .avatar-initials {
    width: 28px;
    height: 28px;
    min-width: 28px;
    font-size: 12px;
    line-height: 28px;
}

/*
    Smaller rows in the account menu, so more of it is on screen at once.

    Measured before: eleven 50px rows, three 25px group labels and a 76px
    profile header came to 763px of content in a 612px panel - 151px of it
    below the fold, which on a phone means the wallet group and the logout are
    only found by scrolling.

    42px rows, 18px icons and 14px text bring it to about 598 and it fits. Not
    smaller than 42: that is already at the floor for something a thumb has to
    hit, and buying two more rows by going to 36 would trade accuracy for a
    scroll nobody was going to need anyway.

    Scoped to the open panel on a phone. The same markup is the desktop
    dropdown and the account sidebar, where 50px rows are right.
*/
@media (max-width: 767.98px) {
    /*
        The row is the li, not the link.

        Shrinking the <a> alone made rows BIGGER - 50px to 54. The li carries
        2px/10px of its own padding and a 1px margin either side, so a link
        given a 42px floor came out at 56 once the li had added its share.
        Both have to come down together.
    */
    #user-navbar.circle_opened .udm-menu-item {
        margin: 0;
        padding-top: 0;
        padding-bottom: 1px;
    }

    #user-navbar.circle_opened .udm-menu-item > a {
        min-height: 40px;
        padding: 6px 14px;
        font-size: 14px;
    }

    #user-navbar.circle_opened .udm-menu-item svg,
    #user-navbar.circle_opened .udm-menu-item img {
        width: 18px;
        height: 18px;
    }

    #user-navbar.circle_opened .udm-menu-group {
        padding-top: 2px;
        padding-bottom: 2px;
        font-size: 11px;
    }

    #user-navbar.circle_opened .udm-header {
        padding-top: 10px;
        padding-bottom: 10px;
    }
}

/*
    The account menu, read from the bar upward.

    Reversed on Alex's call: the panel opens from the bottom, so the row
    nearest the thumb is the one the eye lands on first. column-reverse flips
    the painting order and leaves the DOM alone, which is the part worth
    knowing - tab order and screen readers still follow the source, so the
    two disagree. Acceptable here because it is one short menu and the
    alternative is a second, mobile-only copy of the markup.

    Two levels: the panel itself, which puts the profile row at the bottom,
    and the list, which turns the items over. Turning the list over would put
    each group's label UNDER the items it heads, which is why the labels are
    dropped on a phone - see below.
*/
@media (max-width: 767.98px) {
    #user-navbar.circle_opened > .content.a-menu {
        flex-direction: column-reverse;
    }

    #user-navbar.circle_opened .udm-menu {
        display: flex;
        flex-direction: column-reverse;
    }
}

/*
    No group headings in the phone menu.

    Λογαριασμός / Αγγελίες / Πορτοφόλι earn their place in a sidebar, where the
    eye scans a tall column and the headings give it rungs. In a twelve-row
    panel on a phone they are three rows of furniture in a list short enough to
    read whole - and once the order is reversed each one sits beneath the items
    it is meant to head, which is worse than absent.

    Hidden rather than removed from the markup: the same list is the desktop
    dropdown and the account sidebar, and both keep their headings.
*/
@media (max-width: 767.98px) {
    #user-navbar.circle_opened .udm-menu-group {
        display: none;
    }
}

/*
    The unread count on the header avatar, in place of the blinking dot.

    style.css draws an 8px red circle as #user-navbar.notify > .default:before
    and blinks it. Against a photograph at that size it is easy to look past,
    and it never said how many - which is the thing worth knowing. Both the dot
    and its animation go.

    Same shape, colour and cap as the phone bar's badge so the two surfaces
    speak the same language. Red rather than the brand orange for the same
    reason as there: orange is chrome on this site, and an unread count is news.
*/
#user-navbar.notify > .default:before,
#user-navbar.notify:not(.circle_opened) > span.default:before {
    display: none;
    animation: none;
}

/* The badge is positioned against this. */
#user-navbar > .default {
    position: relative;
}

/*
    Scoped to #user-navbar to win a specificity fight.

    style.css carries `.user-navbar .circle.logged-in > .default > span`,
    which is three classes and an element and matches this badge - so a plain
    `.header-badge.is-empty` lost, and the bubble sat there reading "0" when
    there was nothing to report. The id settles it.
*/
#user-navbar .header-badge {
    position: absolute;
    z-index: 2;
    top: -3px;
    right: -5px;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    box-sizing: border-box;

    /*
        The ring is the page background rather than white: in dark mode a white
        outline around a red disc reads as a halo on a near-black header.
    */
    border: 2px solid var(--body-background-color, #fff);
    border-radius: 9px;
    background: #DC2626;
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    line-height: 14px;
    text-align: center;
    white-space: nowrap;
    pointer-events: none;
}

#user-navbar .header-badge.is-empty {
    display: none;
}

/*
    No account sidebar on the messages page on a phone.

    The sidebar is the account navigation, and on a wide screen it sits beside
    the conversation where it belongs. Stacked on a phone it lands underneath
    the thread - a second copy of the menu, below the content, in the one place
    the reader is trying to have a conversation. The bottom bar carries the same
    menu now, one tap from anywhere, so this is repetition rather than a route.

    Every account page, not just the messages one. The bottom bar carries the
    same menu one tap from anywhere, so stacked under the content this is
    repetition rather than a route.

    account-location goes with it: that is the "Τοποθεσία πωλητή" block, a
    labelled table of country/city/address plus a static map, which on a phone
    sits between the reader and the conversation they opened. The same
    information is now one line under the title - see the chat-location rule
    below and the block that builds it in controllers/my_messages.tpl.

    Whole sections rather than just their contents, so headers and avatars go
    with them. aside.left itself is left in place: it collapses to zero height
    once empty, and hiding it would take any block added there later with it.
*/
@media (max-width: 767.98px) {
    aside.left .account_area,
    aside.left .account-location {
        display: none;
    }
}


/* =============================================
   MESSAGES - THE MEMBER CARD ON A PHONE
   ============================================= */

/*
    The card above the conversation, rearranged for a narrow screen.

    What it was: a 64px avatar, the name, "Μέλος από τις 25.11.2025" wrapping
    onto two lines, a review link, and a solid orange button squeezed into
    whatever width was left - four competing things on one row, and the loudest
    of them the least important. You are on this page to read a conversation;
    the member's other listings are a side trip.

    What it is: avatar and identity on one row, the actions on their own row
    underneath with room to be tapped. The button keeps the brand colour as an
    outline rather than a fill, which is the weight a secondary action should
    carry next to a thread.

    Phone only. The desktop card has a full column and does not have this
    problem.
*/
/*
    The location line on the card is a phone replacement for the sidebar block,
    so it must not appear where that block still does - otherwise a desktop
    reader is told twice. Hidden by default, shown inside the breakpoint.
*/
.messaging-user-info .user-location {
    display: none;
}

@media (max-width: 767.98px) {
    .messaging-user-info .user-info-header {
        display: grid;
        grid-template-columns: auto 1fr;
        align-items: center;
        gap: 12px;
    }

    .messaging-user-info .user-avatar,
    .messaging-user-info .user-avatar .avatar-image,
    .messaging-user-info .user-avatar .avatar-initials {
        width: 48px;
        height: 48px;
        min-width: 48px;
        font-size: 18px;
        line-height: 48px;
    }

    .messaging-user-info .user-main-info {
        min-width: 0;
    }

    .messaging-user-info .user-name {
        font-size: 16px;
        line-height: 1.3;
    }

    /*
        The membership line and the location are context, not headings - one
        step down in size and colour, and each on a single line so the card
        keeps a predictable height.
    */
    .messaging-user-info .user-membership,
    .messaging-user-info .user-location {
        margin-top: 2px;
        color: var(--cat-link-color, #777);
        font-size: 13px;
        line-height: 1.35;
    }

    .messaging-user-info .user-location {
        display: flex;
        align-items: center;
        gap: 5px;
    }

    .messaging-user-info .user-location__icon {
        width: 14px;
        height: 14px;
        flex: none;
        fill: none;
        stroke: currentColor;
        stroke-width: 1.8;
    }

    /*
        Actions span both columns, so they start under the avatar rather than
        being pinched into the gap beside it.
    */
    .messaging-user-info .user-actions {
        grid-column: 1 / -1;
        margin-top: 12px;

        /*
            The theme pushes this row right with margin-left:auto, which in a
            grid cell shrink-wraps it instead of filling the span - the button
            came out 187px of an available 358 and still looked squeezed.
        */
        width: 100%;
        margin-left: 0;
    }

    .messaging-user-info .user-actions .button.view-profile {
        display: block;
        width: 100%;
        padding: 9px 14px;
        border: 1px solid var(--noiz-light-orange, #FF8200);
        border-radius: 10px;
        background: transparent;
        color: var(--noiz-light-orange, #FF8200);
        font-size: 14px;
        text-align: center;
    }
}

/*
    One categories opener on a phone, not two.

    main_menu.tpl now points the header hamburger at the category panel, so the
    "Όλες οι κατηγορίες" control beside the logo is a second button for the same
    thing. It goes, and the header row gets its width back - on a category page
    that leaves the logo and the search icon, which is what that row was for.

    Hidden rather than removed: the hamburger fires this button's own click
    handler, so the element still has to exist.
*/
@media (max-width: 767.98px) {
    .cat-header-row .category-menu__button,
    .top-navigation .category-menu__button {
        display: none;
    }
}

/*
    The hamburger is the text colour, not a filtered orange.

    style.css fills it with --header-icon-fill and then puts
    filter: var(--icon-filter) over the top. In dark mode that is the brand
    orange under brightness(2.5), which lands on a washed-out yellow belonging
    to nothing else on the page.

    --body-font-color instead, which is the white the dark theme already uses
    for its text - #DADADA - and #111 under light, so the icon matches the "El"
    beside it in both without custom.css having to name a colour per theme,
    which it cannot do: light.css and dark.css are mutually exclusive and one of
    them is always disabled.

    The filter has to go too, or it would tint whatever colour is set. Same
    selector as the rule being corrected, so it wins on order rather than by
    escalating specificity.
*/
.main-menu span.menu-button > svg {
    fill: var(--body-font-color);
    filter: none;
}

/*
    The search box moves up beside the logo.

    It was a full-width row of its own under the logo, which cost the header a
    third line on every page that is not a category page. Beside the logo it
    takes whatever the row has left - roughly 250px next to a signed-in
    member's avatar, less beside the wider "Σύνδεση/Εγγραφή" of a signed-out
    one - and the header loses a line either way.

    !important on all three: the wrapper carries Bootstrap's w-100 and
    order-last utilities, which are themselves !important, and this is the same
    fight header.tpl's own comment describes for the category variant of this
    row.
*/
@media (max-width: 767.98px) {
    .top-navigation .col-12.order-last.w-100 {
        order: 2 !important;
        flex: 1 1 auto !important;
        width: auto !important;
        min-width: 0;
    }
}
