/* ===== ShelfStalk design tokens ===== */
:root {
    --paper: #FAFAF9;
    --card: #FFFFFF;
    --ink: #18181B;
    --ink-soft: #6B6B68;
    --line: #E7E5E1;
    --accent: #00A86C;
    --accent-soft: #DBF3EA;
    --sticker-red: #E11D48;
    --sticker-red-soft: #FDE4E9;
    /* Deliberately equal to --accent/--accent-soft, not just a similar
       shade -- the brand color is green now, so "highlighted/brand action"
       and "confirmed/positive" collapsing into one green reads as
       intentional rather than a clash. Kept as separate variables anyway
       so call sites stay self-documenting about which meaning they're using. */
    --confirm-green: #00A86C;
    --confirm-green-soft: #DBF3EA;

    --font-display: 'Space Grotesk', sans-serif;
    --font-body: 'Inter', sans-serif;
    --font-mono: 'Inter', sans-serif;

    --shadow-sm: 0 1px 2px rgba(24,24,27,0.06);
    --shadow-md: 0 4px 16px rgba(24,24,27,0.08);
}

* { box-sizing: border-box; }

body {
    font-family: var(--font-body);
    background: var(--paper);
    color: var(--ink);
    margin: 0;
    padding: 0;
    line-height: 1.5;
}

h1, h2, h3 {
    font-family: var(--font-display);
    font-weight: 700;
    letter-spacing: -0.01em;
    margin: 0 0 12px 0;
}

h1 { font-size: 26px; }
h3 { font-size: 17px; }

a { color: var(--ink); }

/* ===== Nav ===== */
nav {
    background: var(--card);
    border-bottom: 1px solid var(--line);
    padding: 16px 32px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    position: sticky;
    top: 0;
    z-index: 20;
}

.brand {
    display: flex;
    align-items: center;
}

.brand a { display: flex; text-decoration: none; }

.brand-logo {
    height: 34px;
    width: auto;
    display: block;
}

.nav-links {
    display: flex;
    align-items: center;
    gap: 20px;
}

nav a, nav button {
    color: var(--ink-soft);
    text-decoration: none;
    font-family: var(--font-body);
    font-weight: 500;
    font-size: 14px;
    background: none;
    border: none;
    cursor: pointer;
    padding: 0;
    transition: color 0.15s ease;
}

nav a:hover, nav button:hover {
    color: var(--accent);
}

nav span {
    color: var(--ink-soft);
    font-size: 14px;
}

/* ===== Mobile nav ===== */
/* Hidden on wide screens -- the plain horizontal .nav-links row (above)
   is what shows there. Below the breakpoint this becomes the button that
   opens/closes .nav-links as a dropdown (see toggleNavMenu() in
   base.html and the @media block below). */
.nav-toggle {
    display: none;
    background: none;
    border: none;
    box-shadow: none;
    padding: 8px;
    margin: -8px;
    color: var(--ink);
    cursor: pointer;
}

.nav-toggle:hover { background: none; box-shadow: none; transform: none; color: var(--accent); }

/* Swapped via the button's own aria-expanded state (toggleNavMenu() sets
   it) rather than a second JS-driven class, so the icon and the
   open/closed state can never drift out of sync with each other. */
.nav-toggle-icon-close { display: none; }
.nav-toggle[aria-expanded="true"] .nav-toggle-icon-menu { display: none; }
.nav-toggle[aria-expanded="true"] .nav-toggle-icon-close { display: inline-flex; }

@media (max-width: 768px) {
    nav {
        flex-wrap: wrap;
        padding: 14px 20px;
    }

    /* Gated behind .js-nav (set by the inline script in base.html's
       <head>, before anything paints) rather than applying unconditionally
       -- without it, a visitor whose JS fails/is blocked would get a dead
       toggle button and .nav-links stuck at display:none with no way to
       ever reveal it, making every nav link unreachable. With this gate,
       no JS means .nav-links just falls back to its un-media-queried
       display:flex (wrapped by nav's own flex-wrap above), exactly the
       always-visible behavior this feature had before the toggle existed. */
    .js-nav .nav-toggle { display: inline-flex; }

    /* Collapsed by default -- .open (toggled by toggleNavMenu()) reveals
       it as a full-width panel that wraps onto its own row below the
       brand/toggle row, since nav is flex-wrap now and this is the only
       child wide enough (100%) to force that wrap. */
    .js-nav .nav-links {
        display: none;
        flex-direction: column;
        align-items: flex-start;
        gap: 16px;
        width: 100%;
        margin-top: 14px;
        padding-top: 14px;
        border-top: 1px solid var(--line);
    }

    .js-nav .nav-links.open { display: flex; }
}

/* ===== Layout ===== */
.container {
    max-width: 1100px;
    margin: 36px auto;
    padding: 0 24px;
}

@media (max-width: 480px) {
    /* 24px a side is fine down to ~480px; below that (most phones in
       portrait) it starts eating a noticeable share of the screen, so
       this tightens it without going edge-to-edge. */
    .container { margin: 24px auto; padding: 0 16px; }
}

/* ===== Buttons ===== */
button, input[type="submit"] {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 14px;
    background: var(--accent);
    color: #FFFFFF;
    border: none;
    padding: 10px 20px;
    border-radius: 10px;
    cursor: pointer;
    box-shadow: var(--shadow-sm);
    transition: background 0.15s ease, box-shadow 0.15s ease, transform 0.1s ease;
}

.icon { flex-shrink: 0; }

button:hover, input[type="submit"]:hover {
    background: #008F5C;
    box-shadow: var(--shadow-md);
    transform: translateY(-1px);
}

button:active, input[type="submit"]:active {
    transform: translateY(0);
}

.btn-secondary {
    background: var(--card);
    color: var(--ink);
    border: 1px solid var(--line);
    box-shadow: none;
}

.btn-secondary:hover {
    background: var(--paper);
    border-color: var(--ink-soft);
    box-shadow: none;
}

/* ===== Forms ===== */
form p { margin: 14px 0; }

label {
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 13px;
    color: var(--ink-soft);
    display: block;
    margin-bottom: 4px;
}

input[type="text"], input[type="password"], input[type="email"],
input[type="datetime-local"], select, textarea {
    width: 100%;
    padding: 10px 12px;
    font-family: var(--font-body);
    font-size: 14px;
    border: 1px solid var(--line);
    border-radius: 10px;
    background: var(--paper);
    color: var(--ink);
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}

input:focus, select:focus, textarea:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accent-soft);
}

/* Added around every password field by base.html's initPasswordToggles(),
   regardless of which template rendered the field -- a plain <span>
   wrapper needs display:block here since the input inside keeps its own
   width:100% relative to it, and the compound selectors below need the
   extra specificity to win over the plain input[type="password"] rule
   above regardless of source order. */
.pw-toggle-wrap { position: relative; display: block; }
.pw-toggle-wrap input[type="password"],
.pw-toggle-wrap input[type="text"] { padding-right: 40px; }
.pw-toggle-btn {
    position: absolute;
    top: 0;
    right: 0;
    height: 100%;
    width: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    color: var(--ink-soft);
}
.pw-toggle-btn:hover { color: var(--ink); }

/* ===== Filter bar ===== */
/* .filter-form is just the outer card now -- .filter-toolbar (search,
   sort, the Filters toggle, conditional Clear link) is always visible;
   .filter-panel (everything that actually restricts results) is
   collapsed by default and only shown via .open, toggled by the Filters
   button (toggleFiltersPanel() in feed.html). Search/sort stay outside
   the panel since they change how already-shown results are found/
   ordered rather than restricting which ones show at all -- same split
   as the mobile Filters button/modal (that Filters button/modal is
   mobile's version of exactly this collapse). */
.filter-form {
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: 14px;
    padding: 16px 18px;
    margin-bottom: 24px;
}

.search-row {
    display: flex;
    align-items: flex-end;
    gap: 8px;
}

/* Only shown at phone width (below) -- wide screens have room for the
   whole toolbar at once. */
.filter-more {
    display: none;
    position: relative;
    flex: none;
    width: 44px;
    height: 44px;
    padding: 0;
    justify-content: center;
    background: var(--paper);
    color: var(--ink);
    border: 1px solid var(--line);
    box-shadow: none;
}
.filter-more:hover { background: var(--paper); box-shadow: none; transform: none; }
.filter-more[aria-expanded="true"] { border-color: var(--accent); color: var(--accent); }
.filter-more-count {
    position: absolute;
    top: -6px;
    right: -6px;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: 9px;
    background: var(--accent);
    color: #FFFFFF;
    font-size: 11px;
    font-weight: 700;
    line-height: 18px;
    text-align: center;
}

.filter-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 14px;
}

.filter-panel {
    display: none;
    flex-wrap: wrap;
    align-items: center;
    gap: 14px;
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--line);
}

.filter-panel.open {
    display: flex;
}

.filters-toggle {
    background: var(--paper);
    color: var(--ink);
    border: 1px solid var(--line);
    box-shadow: none;
    padding: 10px 14px;
}

.filters-toggle:hover {
    background: var(--paper);
    border-color: var(--ink-soft);
    box-shadow: none;
    transform: none;
}

.clear-filters-link {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-family: var(--font-body);
    font-size: 13px;
    font-weight: 500;
    color: var(--ink-soft);
    text-decoration: none;
}

.clear-filters-link:hover {
    color: var(--sticker-red);
}

.multi-filter-all-option {
    font-weight: 600;
    border-bottom: 1px solid var(--line);
    padding-bottom: 8px;
    margin-bottom: 4px;
}

.filter-form label {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin: 0;
    font-size: 12px;
}

.filter-form input[type="text"], .filter-form select {
    width: auto;
    min-width: 140px;
}

@media (max-width: 768px) {
    /* min-width:140px flex-wrapping this many fields (keyword+sort in the
       toolbar; 5 multi-filter dropdowns + discount min/max in the panel)
       reads as a ragged 2-per-row grid at phone widths -- a single
       stacked column is the more usual, cleaner shape for a mobile
       filter panel. */
    .filter-toolbar, .filter-panel { flex-direction: column; align-items: stretch; }
    .filter-form input[type="text"], .filter-form select { width: 100%; min-width: 0; }
    .multi-filter, .multi-filter-toggle, .filters-toggle { width: 100%; }
    /* A dropdown anchored to a now full-width toggle would otherwise
       stretch just as wide, wrapping every option label awkwardly --
       sized to content instead, same as it is on wider screens. */
    .multi-filter-panel { width: max-content; max-width: calc(100vw - 64px); }

    /* Collapsed to just search + the sliders button until that's tapped,
       so the deals start near the top of the screen. Gated behind .js-nav
       like the nav menu: without JS everything stays visible. */
    .js-nav .filter-more { display: inline-flex; }
    .js-nav .search-label-text { display: none; }
    .search-row label { flex: 1; min-width: 0; }
    .js-nav .filter-form:not(.mobile-open) { padding: 10px 12px; margin-bottom: 16px; }
    .js-nav .filter-form:not(.mobile-open) .filter-toolbar > :not(.search-row),
    .js-nav .filter-form:not(.mobile-open) .filter-panel { display: none; }
}

/* ===== Multi-select filter dropdowns ===== */
/* Reusable across category/discount-type/country/state/city -- see
   deals/templates/deals/_multi_filter.html, included once per filter in
   feed.html. One checkbox-dropdown component instead of five separate
   ad-hoc ones. */
.multi-filter {
    position: relative;
}

.multi-filter-toggle {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-family: var(--font-body);
    font-weight: 500;
    font-size: 14px;
    color: var(--ink);
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 10px;
    padding: 10px 12px;
    cursor: pointer;
    box-shadow: none;
}

/* Resets the global button/input[type=submit] hover (green lift) the
   same way .chip:hover and .btn-secondary:hover already do elsewhere in
   this file -- this should read as a plain outlined toggle, not a
   primary action. */
.multi-filter-toggle:hover {
    background: var(--paper);
    border-color: var(--ink-soft);
    box-shadow: none;
    transform: none;
}

.multi-filter-count {
    color: var(--accent);
    font-weight: 700;
}

.multi-filter-panel {
    display: none;
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    z-index: 15;
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: 10px;
    box-shadow: var(--shadow-md);
    padding: 8px;
    min-width: 200px;
    max-height: 260px;
    overflow-y: auto;
}

.multi-filter-panel.open {
    display: block;
}

/* Overrides .filter-form label's flex-direction:column (a checkbox +
   its text should sit side by side, not stacked) -- needs the element
   type in the selector to match that rule's own specificity and win the
   tie on source order, since a bare class selector alone wouldn't. */
label.multi-filter-option {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 8px;
    padding: 6px 8px;
    margin: 0;
    border-radius: 6px;
    font-family: var(--font-body);
    font-weight: 400;
    font-size: 14px;
    color: var(--ink);
    cursor: pointer;
    white-space: nowrap;
}

label.multi-filter-option:hover {
    background: var(--paper);
}

.multi-filter-option input[type="checkbox"] {
    width: auto;
    margin: 0;
}

/* Kept for search engines and screen readers, not shown on screen (the
   feed's page headings). */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

/* ===== Logged-out intro (feed.html) ===== */
/* One compact row: prize line on the left, Sign up on the right, so the
   deals start near the top of the screen. The headline is hidden
   visually but kept for search engines and screen readers. */
.hero {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: 16px;
    background: var(--accent-soft);
    border-radius: 14px;
    padding: 14px 18px;
    margin-bottom: 16px;
}
.hero p { margin: 0; font-size: 15px; line-height: 1.4; }
.hero .hero-prize { font-weight: 600; }
.hero .hero-terms { font-size: 12px; font-weight: 400; color: var(--ink-soft); white-space: nowrap; }
.hero-btn {
    display: inline-flex;
    align-items: center;
    font-weight: 600;
    font-size: 14px;
    background: var(--accent);
    color: #FFFFFF;
    padding: 10px 20px;
    border-radius: 10px;
    text-decoration: none;
    white-space: nowrap;
    box-shadow: var(--shadow-sm);
}
.hero-btn:hover { background: #008F5C; }
.hero-actions { display: flex; gap: 10px; }
.hero-btn-secondary {
    background: var(--card);
    color: var(--ink);
    border: 1px solid var(--line);
}
.hero-btn-secondary:hover { background: var(--paper); }
@media (max-width: 480px) {
    /* Too narrow for text plus two buttons side by side: the buttons
       stack in the right-hand column instead. */
    .hero-actions { flex-direction: column; gap: 6px; }
    .hero { gap: 10px; padding: 10px 12px; margin-bottom: 12px; border-radius: 12px; }
    .hero p { font-size: 13px; line-height: 1.35; }
    .hero .hero-terms { font-size: 11px; }
    .hero-btn { font-size: 13px; padding: 8px 12px; }
}

/* ===== Feed grid ===== */
.deal-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    gap: 24px;
}

/* ===== Deal cards ===== */
.deal-card {
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: 16px;
    padding: 0 0 18px 0;
    margin-bottom: 0;
    position: relative;
    overflow: hidden;
    box-shadow: var(--shadow-sm);
    transition: box-shadow 0.2s ease, transform 0.2s ease;
}

.deal-card:hover {
    box-shadow: var(--shadow-md);
    transform: translateY(-2px);
}

.deal-card img {
    max-width: 100%;
    display: block;
}

.deal-tag {
    position: absolute;
    top: 12px;
    left: 12px;
    background: var(--card);
    color: var(--ink);
    font-family: var(--font-body);
    font-size: 11px;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    padding: 5px 12px;
    border-radius: 999px;
    box-shadow: var(--shadow-sm);
    z-index: 2;
}

.deal-tag::before { content: none; }

.deal-card .deal-body {
    padding: 16px 18px 0 18px;
    position: relative;
}

.deal-card .deal-body::before { content: none; }

.deal-card h3 { margin-top: 4px; }
.deal-body > h3 { margin-bottom: 6px; }

/* Feed card's compact info lines (feed.html) -- replaces the old one
   labelled row per field. */
.deal-card p.deal-meta {
    margin: 2px 0;
    font-size: 13px;
    line-height: 1.45;
}
.deal-card p.deal-meta .icon { vertical-align: -2px; margin-right: 2px; }

.deal-actions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    column-gap: 16px;
}
.deal-actions .directions-link { margin: 8px 0; }
.deal-comment-count { margin-left: auto; font-size: 13px; color: var(--ink-soft); }

/* Feed cards only (deal_detail keeps the roomier chips). Small enough
   that all four usually fit on one row at phone width. */
.deal-card .deal-body > .vote-buttons { margin-top: 6px; padding-top: 10px; gap: 6px; }
.deal-card .deal-body > .vote-buttons .chip { font-size: 12px; padding: 5px 10px; }

/* The feed's folded comments (details/summary in feed.html). */
details.comments-section { margin-top: 10px; padding: 10px 0; }
details.comments-section > summary {
    cursor: pointer;
    font-family: var(--font-body);
    font-size: 13px;
    font-weight: 600;
    color: var(--ink);
}
details.comments-section[open] > summary { margin-bottom: 10px; }

.deal-card p {
    margin: 6px 0;
    font-size: 14px;
    color: var(--ink-soft);
}

.deal-card p strong {
    color: var(--ink);
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.02em;
}

.discount-badge-overlay {
    position: absolute;
    top: 12px;
    right: 12px;
    background: var(--accent);
    color: #FFFFFF;
    box-shadow: var(--shadow-sm);
    z-index: 2;
    margin: 0;
}

/* ===== Latest-vote trend badge ===== */
.trend-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-family: var(--font-body);
    font-size: 12px;
    font-weight: 700;
    border-radius: 8px;
    padding: 4px 8px;
    margin: 6px 0;
}

/* ===== Vote / action chips ===== */
.vote-buttons {
    margin-top: 14px;
    padding-top: 14px;
    border-top: 1px solid var(--line);
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-family: var(--font-body);
    font-size: 13px;
    font-weight: 600;
    color: var(--ink-soft);
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: 20px;
    padding: 6px 13px;
    text-decoration: none;
    cursor: pointer;
    transition: border-color 0.15s ease, color 0.15s ease, background-color 0.15s ease;
}

/* The "Save" chip is a real <button> (the vote chips are <a> tags), so
   without these resets the global button:hover rule's green background/
   shadow/lift (higher specificity than .chip:hover alone provides for
   those specific properties) would win over the subtle border-only hover
   intended here -- same clash .list-option-row:hover already guards
   against below. */
.chip:hover { border-color: var(--ink-soft); background: var(--card); box-shadow: none; transform: none; }
.chip-confirm:hover { color: var(--confirm-green); border-color: var(--confirm-green); background: var(--confirm-green-soft); }
.chip-gone:hover { color: var(--ink); border-color: var(--ink-soft); }
.chip-spam:hover { color: var(--sticker-red); border-color: var(--sticker-red); background: var(--sticker-red-soft); }

/* ===== Location picker ===== */
.location-picker {
    background: var(--card);
    border: 1px solid var(--line);
    padding: 18px;
    border-radius: 14px;
    margin-bottom: 18px;
    position: relative;
}

.location-picker input[type="text"] {
    margin-top: 6px;
}

.suggestions-box {
    position: relative;
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: 10px;
    max-height: 200px;
    overflow-y: auto;
    z-index: 10;
    margin-top: 4px;
}

.suggestion-item {
    padding: 9px 12px;
    cursor: pointer;
    border-bottom: 1px solid var(--line);
    font-size: 14px;
}

.suggestion-item:last-child { border-bottom: none; }

.suggestion-item:hover {
    background: var(--paper);
}

#selected-location {
    background: var(--confirm-green-soft);
    border: 1px solid var(--confirm-green);
    padding: 10px 14px;
    border-radius: 10px;
    font-size: 14px;
}

#selected-location a { color: var(--confirm-green); font-weight: 600; }

#show-map-fallback {
    display: inline-block;
    margin-top: 8px;
    font-size: 13px;
    color: var(--ink-soft);
}

/* Shared by every page including _location_picker.html (post_deal.html,
   signup.html) -- moved here from post_deal.html's own extra_head block
   so a second including page doesn't need to repeat it. */
#map-fallback { display:none; margin-top:14px; }
#pin-map { height: 300px; border-radius: 10px; margin-top: 8px; overflow: hidden; }
@media (max-width: 480px) {
    /* 300px is a big chunk of a phone's viewport height on a form that's
       already long -- shorter still leaves plenty of room to see and
       drag the pin. */
    #pin-map { height: 220px; }
}

/* ===== Extra photos gallery ===== */
.extra-photos {
    display: flex;
    gap: 8px;
    margin: 10px 0;
    flex-wrap: wrap;
}

.extra-photo-thumb {
    width: 100px;
    height: 100px;
    object-fit: cover;
    border-radius: 10px;
    border: 1px solid var(--line);
    cursor: zoom-in;
}

/* ===== Error / status messages ===== */
.error-message {
    background: var(--sticker-red-soft);
    border: 1px solid var(--sticker-red);
    color: #A3123B;
    padding: 10px 14px;
    border-radius: 10px;
    font-size: 14px;
    margin-bottom: 16px;
}

/* Same look as .error-message, kept as its own class -- see the comment in
   _location_picker.html for why. */
.location-picker-error {
    background: var(--sticker-red-soft);
    border: 1px solid var(--sticker-red);
    color: #A3123B;
    padding: 10px 14px;
    border-radius: 10px;
    font-size: 14px;
    margin-top: 10px;
}

.success-message {
    background: var(--confirm-green-soft);
    border: 1px solid var(--confirm-green);
    color: #0F5C2E;
    padding: 10px 14px;
    border-radius: 10px;
    font-size: 14px;
    margin-bottom: 16px;
}

/* ===== Password strength checklist (signup form) ===== */
.password-checklist {
    list-style: none;
    margin: 6px 0 14px;
    padding: 0;
    font-size: 13px;
    color: var(--ink-soft);
}

.password-checklist li {
    padding: 2px 0;
}

.password-checklist li::before {
    content: "○";
    display: inline-block;
    width: 18px;
    color: var(--ink-soft);
}

.password-checklist li.met {
    color: var(--confirm-green);
}

.password-checklist li.met::before {
    content: "●";
    color: var(--confirm-green);
}

/* ===== Inline live-validation hints (signup: password match, username
   availability, email format) ===== */
.inline-hint {
    display: block;
    font-size: 13px;
    margin: 0;
    max-height: 0;
    opacity: 0;
    overflow: hidden;
    transform: translateY(-4px);
    transition: opacity 0.2s ease, transform 0.2s ease, max-height 0.2s ease, margin 0.2s ease;
}

.inline-hint.visible {
    margin: 6px 0 14px;
    max-height: 40px;
    opacity: 1;
    transform: translateY(0);
}

.inline-hint.ok { color: var(--confirm-green); }
.inline-hint.error { color: #A3123B; }
.inline-hint.checking { color: var(--ink-soft); }

/* ===== Dismissible toast popups (error/success messages, incl. signup) =====
   .toast reuses .error-message/.success-message for color/border -- only
   position/animation/layout live here, so those two classes still look
   right on their own wherever else they're used (e.g. post_deal.html's
   inline AJAX error, which is never a toast). */
.toast-stack {
    position: fixed;
    top: 16px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 200;
    display: flex;
    flex-direction: column;
    gap: 8px;
    width: min(92vw, 420px);
}

.toast {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 0;
    box-shadow: 0 6px 20px rgba(24, 24, 27, 0.15);
    animation: toast-in 0.25s ease-out;
}

.toast.toast-leaving {
    animation: toast-out 0.2s ease-in forwards;
}

.toast-close {
    background: none;
    border: none;
    cursor: pointer;
    font-size: 18px;
    line-height: 1;
    color: inherit;
    padding: 0;
    opacity: 0.6;
    flex-shrink: 0;
}

.toast-close:hover { opacity: 1; }

@keyframes toast-in {
    from { opacity: 0; transform: translateY(-12px); }
    to { opacity: 1; transform: translateY(0); }
}

@keyframes toast-out {
    from { opacity: 1; transform: translateY(0); }
    to { opacity: 0; transform: translateY(-12px); }
}

/* ===== Lightbox ===== */
#lightbox-overlay {
    display: none;
    position: fixed;
    top: 0; left: 0; right: 0; bottom: 0;
    background: rgba(24, 24, 27, 0.9);
    z-index: 100;
    align-items: center;
    justify-content: center;
    cursor: zoom-out;
    padding: 30px;
}

#lightbox-overlay img {
    max-width: 90%;
    max-height: 90%;
    border-radius: 10px;
    box-shadow: 0 10px 40px rgba(0,0,0,0.4);
}

/* ===== Carousel ===== */
.carousel {
    position: relative;
    overflow: hidden;
}

.carousel-track {
    display: flex;
    overflow-x: hidden;
    scroll-snap-type: x mandatory;
}

.carousel-track img {
    flex: 0 0 100%;
    width: 100%;
    height: 220px;
    object-fit: cover;
    scroll-snap-align: start;
    cursor: zoom-in;
    display: block;
}

.carousel-btn {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    background: rgba(24, 24, 27, 0.55);
    color: #FFFFFF;
    border: none;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
    z-index: 3;
    box-shadow: none;
}

.carousel-btn:hover { background: rgba(24, 24, 27, 0.8); box-shadow: none; transform: translateY(-50%); }
.carousel-btn.prev { left: 8px; }
.carousel-btn.next { right: 8px; }

/* ===== Directions link ===== */
.directions-link {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin: 8px 8px 8px 0;
    font-family: var(--font-body);
    font-size: 13px;
    font-weight: 500;
    color: var(--accent);
    text-decoration: none;
}

/* ===== Report links (deal / comment) ===== */
.report-link {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-family: var(--font-body);
    font-size: 13px;
    color: var(--ink-soft);
    text-decoration: none;
}

.report-link:hover { color: var(--sticker-red); }

/* Resets the global button/input[type=submit] rule's background, padding,
   shadow, and hover lift -- for a <button> (needs to POST, so it can't be
   a plain <a>) that should otherwise look and behave exactly like a
   .report-link text link. */
.link-button {
    background: none;
    border: none;
    box-shadow: none;
    padding: 0;
    cursor: pointer;
}

.link-button:hover { background: none; box-shadow: none; transform: none; }

.directions-link:hover { text-decoration: underline; }

/* ===== Comments ===== */
.comments-section {
    margin-top: 16px;
    padding-top: 16px;
    border-top: 1px solid var(--line);
}

.comments-section h3 { font-size: 14px; margin-bottom: 10px; }

.comment-form textarea {
    width: 100%;
    padding: 10px 12px;
    font-family: var(--font-body);
    font-size: 14px;
    border: 1px solid var(--line);
    border-radius: 10px;
    resize: vertical;
    margin-bottom: 8px;
}

.comment {
    background: var(--paper);
    border-radius: 10px;
    padding: 10px 12px;
    margin-top: 10px;
}

.comment-meta {
    font-family: var(--font-body);
    font-size: 12px;
    color: var(--ink-soft);
    margin: 0 0 4px 0;
}

.comment p:last-child {
    margin: 0;
    font-size: 14px;
}

/* ===== Save-to-list modal (also used by deal_detail.html) ===== */
.modal-overlay {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
    z-index: 30;
    align-items: center;
    justify-content: center;
    padding: 20px;
}

.modal-card {
    max-width: 380px;
    width: 100%;
    padding: 20px;
}

.list-option-row {
    display: block;
    width: 100%;
    text-align: left;
    padding: 10px 12px;
    margin-bottom: 6px;
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: 8px;
    font-family: var(--font-body);
    font-size: 14px;
    font-weight: 600;
    color: var(--ink);
    box-shadow: none;
}

.list-option-row:hover {
    border-color: var(--accent);
    background: var(--accent-soft);
    color: var(--accent);
    box-shadow: none;
    transform: none;
}

.new-list-row {
    display: flex;
    gap: 8px;
    margin-bottom: 10px;
}

.new-list-row input {
    flex: 1;
}

.business-badge {
    display: inline-block;
    font-size: 11px;
    font-weight: 600;
    color: var(--accent);
    background: var(--accent-soft);
    border: 1px solid var(--accent);
    padding: 2px 8px;
    border-radius: 999px;
    margin-left: 4px;
}

.tier-badge {
    display: inline-block;
    font-size: 11px;
    font-weight: 600;
    color: var(--ink-soft);
    background: var(--paper);
    border: 1px solid var(--line);
    padding: 2px 8px;
    border-radius: 999px;
    margin-left: 4px;
}

.leaderboard-me {
    background: var(--accent-soft) !important;
    border: 1px solid var(--accent);
}
/* Price-drop deals: "~~€10.00~~ → €6.00" under the title (_price_line.html) */
.price-line {
    margin: 2px 0 6px;
    font-size: 15px;
}
.price-line s {
    color: var(--ink-soft);
}
.price-line strong {
    color: var(--confirm-green);
}


/* Feed Phase 2 spotlight card (deals/templates/deals/_feed_card.html) */
.feed-card {
    display: flex;
    align-items: center;
    gap: 16px;
    background: #003328;
    border-radius: 16px;
    padding: 16px 20px;
    margin-bottom: 16px;
    box-shadow: var(--shadow-sm);
}
.feed-card .fc-photo { width: 84px; height: 84px; object-fit: cover; border-radius: 12px; flex-shrink: 0; }
.feed-card .fc-text { flex: 1; min-width: 0; }
.feed-card p { margin: 0; }
.feed-card .fc-title { font-size: 12px; font-weight: 800; letter-spacing: 1.5px; text-transform: uppercase; color: #F8B030; }
.feed-card .fc-line1 { margin-top: 6px; font-size: 17px; font-weight: 700; color: #FFFFFF; }
.feed-card .fc-line2 { margin-top: 2px; font-size: 14px; color: rgba(255, 255, 255, 0.85); }
.feed-card .fc-cta {
    flex-shrink: 0;
    background: #F8B030;
    color: #003328;
    font-weight: 800;
    font-size: 14px;
    padding: 10px 18px;
    border-radius: 999px;
    text-decoration: none;
    white-space: nowrap;
}
@media (max-width: 600px) {
    .feed-card { flex-wrap: wrap; }
    .feed-card .fc-cta { margin-left: auto; }
}

.feed-cards { margin-bottom: 16px; }
.feed-cards .feed-card { margin-bottom: 0; }
.feed-cards .fc-dots { display: flex; justify-content: center; gap: 6px; margin-top: 8px; }
.feed-cards .fc-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--line, #E7E5E1); }
.feed-cards .fc-dot.active { background: #003328; }

/* Feed back-to-top button (feed.html) */
.back-to-top {
    position: fixed;
    right: 20px;
    bottom: 24px;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    border: none;
    background: #003328;
    color: #fff;
    font-size: 22px;
    line-height: 48px;
    padding: 0;
    cursor: pointer;
    box-shadow: var(--shadow-md);
    z-index: 50;
}
.back-to-top[hidden] { display: none; }

/* Profile settings cards: newspaper-style columns instead of a grid, so a
   short card (Profile photo) doesn't leave a gap beside a tall one
   (Account settings); each card sits straight under the one above. */
.settings-columns { columns: 2 340px; column-gap: 24px; margin-bottom: 24px; }
.settings-columns > .deal-card { break-inside: avoid; display: inline-block; width: 100%; margin-bottom: 24px; }
.settings-columns > .deal-card:hover { transform: none; }

/* Profile: collapsible sections (points history, account settings) */
.collapsible-card { padding: 0; margin-bottom: 24px; }
.collapsible-card > summary,
.settings-section > summary {
    list-style: none;
    cursor: pointer;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 12px;
    padding: 18px 20px;
}
.collapsible-card > summary::-webkit-details-marker,
.settings-section > summary::-webkit-details-marker { display: none; }
.collapsible-card > summary::before,
.settings-section > summary::before { content: "\25B8"; color: var(--accent); transition: transform 0.15s ease; }
.collapsible-card[open] > summary::before,
.settings-section[open] > summary::before { transform: rotate(90deg); }
.collapsible-title { font-weight: 700; font-size: 18px; color: var(--ink); }
.collapsible-meta { font-size: 13px; color: var(--ink-soft); }
.collapsible-body { padding: 0 20px 18px; }
.collapsible-card:hover { transform: none; }
.settings-section {
    background: var(--card);
    border: 1px solid var(--line);
    border-radius: 16px;
    margin-bottom: 24px;
    box-shadow: var(--shadow-sm);
}
.settings-section[open] { padding-bottom: 4px; }
.settings-section .settings-columns { padding: 0 20px; margin-bottom: 0; }
.show-more-btn { margin-top: 6px; width: 100%; }
