/* ==========================
   SINGLE SHOP PAGE
========================== */

.single-shop__hero {
    position: relative;
    border-radius: var(--radius-lg);
    overflow: hidden;
    aspect-ratio: 45 / 15;
    margin-bottom: 2rem;
}

.single-shop__hero img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.single-shop__hero .shop-card__badges {
    position: absolute;
    top: 1rem;
    left: 1rem;
}

/* Fallback when a shop has no featured image — same background/logo
   treatment as .shop-card__media--placeholder, sized for this larger,
   wider (21:9) band instead of a grid card. */
.single-shop__hero--placeholder {
    background: var(--color-secondary);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2rem;
}

.single-shop__hero--placeholder .single-shop__placeholder-logo {
    width: 40%;
    height: auto;
    object-fit: contain;
}

.single-shop__layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(280px, 340px);
    gap: 2.5rem;
    align-items: start;
}

.single-shop__title {
    margin-bottom: 0.5rem;
}

.single-shop__tagline {
    color: var(--color-text-light);
    font-size: 1.05rem;
}

.single-shop__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    margin-top: 1.5rem;
}

.single-shop__divider {
    border: none;
    border-top: var(--border-soft);
    margin: 1.5rem 0;
}

/* Follow + Share live in one combined row: Follow links to the shop's own
   social channels, Share re-shares this directory listing — different
   actions, but visually one strip rather than two stacked ones. Follow
   (when present) comes first, separated from Share by a thin vertical
   divider; Share always renders (Copy Link + Facebook only — Facebook is
   the dominant platform local businesses in the Philippines actually use,
   Copy Link covers everything else without a button per platform). */
.single-shop__social-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.6rem;
    margin-top: 1rem;
}

.single-shop__social-label,
.single-shop__share-label {
    font-size: 0.85rem;
    color: var(--color-text-light);
}

.single-shop__social-divider {
    width: 0;
    height: 1.25rem;
    border-left: var(--border-soft);
    margin: 0 0.15rem;
}

.single-shop__share-btn {
    -webkit-appearance: none;
    appearance: none;
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    flex-shrink: 0;
    border-radius: 50%;
    border: none;
    background: var(--color-muted);
    color: var(--color-text-dark);
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: background 0.2s ease, color 0.2s ease, transform 0.15s ease;
}

/* Explicitly re-assert the resting background AND icon color on every
   interactive state — same reasoning as .menu-tabs__tab: a browser default
   (native <button> chrome, or a default link/focus color) can apply its own
   styling on hover/active/focus that isn't overridden just by setting it on
   the resting state above. The icon color re-assertion matters because the
   SVGs use fill/stroke="currentColor" — if `color` shifts on hover for any
   reason, the icon shifts with it even though nothing here intends that.
   Scoped to exclude Facebook (an <a>, not a <button> — not exposed to native
   button chrome, and has its own blue background + white icon that this
   reassertion would otherwise clobber on hover). */
.single-shop__share-btn:not(.single-shop__share-btn--facebook):hover,
.single-shop__share-btn:not(.single-shop__share-btn--facebook):active,
.single-shop__share-btn:not(.single-shop__share-btn--facebook):focus {
    background: var(--color-muted);
    color: var(--color-text-dark);
}

.single-shop__share-btn--facebook:hover,
.single-shop__share-btn--facebook:active,
.single-shop__share-btn--facebook:focus {
    background: #1877f2;
    color: #fff;
}

/* Tooltip: pure CSS, driven by data-tooltip so JS can swap its text (e.g. to
   "Copied!") without needing a second element to manage. Hidden via opacity/
   pointer-events rather than display, so the position/transform transition
   can animate in on hover/focus instead of just popping into place. */
.single-shop__share-btn::after,
.single-shop__social-btn::after {
    content: attr(data-tooltip);
    position: absolute;
    bottom: calc(100% + 0.5rem);
    left: 50%;
    transform: translateX(-50%) translateY(4px);
    background: var(--color-text-dark);
    color: #fff;
    font-size: 0.75rem;
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
    padding: 0.4rem 0.65rem;
    border-radius: var(--radius-sm);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease, transform 0.15s ease;
    z-index: 5;
}

.single-shop__share-btn::before,
.single-shop__social-btn::before {
    content: '';
    position: absolute;
    bottom: calc(100% + 0.2rem);
    left: 50%;
    transform: translateX(-50%);
    border: 5px solid transparent;
    border-top-color: var(--color-text-dark);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.15s ease;
    z-index: 5;
}

.single-shop__share-btn:hover::after,
.single-shop__share-btn:hover::before,
.single-shop__share-btn:focus-visible::after,
.single-shop__share-btn:focus-visible::before,
.single-shop__social-btn:hover::after,
.single-shop__social-btn:hover::before,
.single-shop__social-btn:focus-visible::after,
.single-shop__social-btn:focus-visible::before {
    opacity: 1;
    transform: translateX(-50%) translateY(0);
}

.single-shop__share-btn:hover::before,
.single-shop__share-btn:focus-visible::before,
.single-shop__social-btn:hover::before,
.single-shop__social-btn:focus-visible::before {
    transform: translateX(-50%);
}

.single-shop__share-btn svg,
.single-shop__social-btn svg {
    width: 1.15rem;
    height: 1.15rem;
    flex-shrink: 0;
}

.single-shop__share-btn--facebook {
    background: #1877f2;
    color: #fff;
}

/* Neither share button recolors on hover/focus — both just lift via
   translateY. .is-copied is a separate, click-triggered confirmation state,
   not a hover effect, so it keeps its own background change. Social buttons
   (below) use the same lift but also brighten slightly on hover, since
   unlike Share they have no neutral/branded split to preserve. */
.single-shop__share-btn:hover,
.single-shop__share-btn:focus {
    transform: translateY(-1px);
}

.single-shop__share-btn.is-copied {
    background: var(--color-primary);
    color: #fff;
}

.single-shop__share-btn:focus-visible,
.single-shop__social-btn:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
}

.single-shop__share-icon--check {
    display: none;
}

.single-shop__share-btn.is-copied .single-shop__share-icon--link {
    display: none;
}

.single-shop__share-btn.is-copied .single-shop__share-icon--check {
    display: block;
}

/* Follow buttons: the shop's own social channels, sharing the combined row
   above with Share — some of these small local shops have no real website
   at all, only a Facebook/Instagram/TikTok presence, so this is often the
   more useful outbound link. Same icon-only circular button shape as Share
   for visual consistency, but each platform keeps its own brand background
   permanently (no neutral state to preserve), so hover is just a lift +
   brightness bump. */
.single-shop__social-btn {
    -webkit-appearance: none;
    appearance: none;
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    flex-shrink: 0;
    border-radius: 50%;
    border: none;
    color: #fff;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: transform 0.15s ease, filter 0.2s ease;
}

.single-shop__social-btn:hover,
.single-shop__social-btn:focus {
    transform: translateY(-1px);
    filter: brightness(1.1);
}

/* Instagram's real mark uses a gradient, not a flat color — approximated
   here rather than picked from Meta's own brand kit; swap for the official
   asset before launch if pixel-exact brand fidelity matters, same caveat as
   the Facebook glyph above. TikTok's icon below is a simplified musical-note
   glyph built from plain shapes (circle + a straight/curved path), not the
   official multi-layer brand mark — deliberately simple, verifiable geometry
   rather than a memorized path, same reasoning as the Copy Link chain icon. */
.single-shop__social-btn--facebook {
    background: #1877f2;
}

.single-shop__social-btn--instagram {
    background: linear-gradient(45deg, #f9ce34, #ee2a7b, #6228d7);
}

.single-shop__social-btn--tiktok {
    background: #010101;
}

.single-shop__sidebar {
    position: sticky;
    top: calc(100px + 1.5rem);
}

.single-shop__sidebar-title {
    font-size: 1.05rem;
    margin-bottom: 1rem;
}

/* Sidebar quick-facts: icon + a stacked label/value pair, e.g.
   [pin icon] "Location" / "123 Rizal St..." — replaces an earlier inline
   single-line treatment per a reference mockup the user shared. */
.single-shop__info-row {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-bottom: 1.5rem;
}

.single-shop__info-row:last-child {
    margin-bottom: 0;
}

.single-shop__info-icon {
    width: 1.4rem;
    height: 1.4rem;
    flex-shrink: 0;
    color: var(--color-text-light);
}

.single-shop__info-text {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.single-shop__info-label {
    font-size: 0.85rem;
    color: var(--color-text-light);
}

.single-shop__info-value {
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--color-text-dark);
}

.single-shop__tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

/* Leaflet needs an explicit height on its container or it renders at 0px.
   Lives in the main column now (moved out of the sidebar so the Menu could
   take its place there), so it gets a taller, wider glance than the old
   180px sidebar-width version — still not a full interactive map though
   (scrollWheelZoom is disabled in shop-map.js so it doesn't hijack page
   scroll). */
.single-shop__map {
    width: 100%;
    height: 180px;
    border-radius: var(--radius-md);
    margin: 1rem 0;
    overflow: hidden;
}

.single-shop__map--main {
    height: 340px;
}

.single-shop__map-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-bottom: 1.5rem;
}

.single-shop__map-actions .btn {
    flex: 1;
    justify-content: center;
    font-size: 0.85rem;
    padding: 0.5rem 0.75rem;
}

/* Full weekly schedule — its own section between the main content and
   Related Shops, separate from the sidebar's quick "today only" line. All 7
   days listed individually (not grouped) with today's row highlighted —
   matches how Google Business Profile/Yelp display hours, a familiar pattern
   that answers "is today different" at a glance without cross-referencing
   the sidebar. Stacked single-column rows, not a grid, so the highlight
   reads clearly against the rest. */
.single-shop__weekly-hours {
    padding: 0;
    overflow: hidden; /* clips a highlighted first/last row to the card's rounded corners */
}

.section__eyebrow + .single-shop__weekly-hours {
    margin-top: 1rem;
}

.single-shop__weekly-hours-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem;
    padding: 1rem 1.5rem;
    border-bottom: var(--border-soft);
}

.single-shop__weekly-hours-row:last-child {
    border-bottom: none;
}

.single-shop__weekly-hours-row.is-today {
    background: var(--color-muted);
}

.single-shop__weekly-hours-day {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    color: var(--color-text-light);
}

.single-shop__weekly-hours-row.is-today .single-shop__weekly-hours-day,
.single-shop__weekly-hours-row.is-today .single-shop__weekly-hours-time {
    color: var(--color-text-dark);
    font-weight: 600;
}

.single-shop__today-badge {
    color: var(--color-primary);
    font-size: 0.8rem;
    font-weight: 700;
}

.single-shop__weekly-hours-time {
    color: var(--color-text-light);
}

/* ==========================
   MENU (tabbed categories)
   Toggled via assets/js/menu-tabs.js — a fixed, uniform set of category
   tabs (see inc/menu.php); a tab only renders at all if that category has
   at least one item, so there's no empty/greyed-out state to style.
========================== */

.menu-tabs {
    position: relative;
    display: flex;
    flex-wrap: wrap;
    gap: 1.5rem;
    border-bottom: var(--border-soft);
    margin: 1rem 0 1.5rem;
}

.menu-tabs__tab {
    -webkit-appearance: none;
    appearance: none;
    -webkit-tap-highlight-color: transparent;
    background: none;
    border: none;
    padding: 0.5rem 0 0.85rem;
    font-family: var(--font-primary);
    font-size: 1rem;
    color: var(--color-text-light);
    cursor: pointer;
    transition: color 0.2s ease;
}

/* Explicitly re-assert no background on every interactive state — some
   browsers apply a native <button> highlight on hover/active/focus that
   isn't overridden just by setting background: none on the resting state
   above. :focus specifically is what was still showing a background after a
   click, since it persists after the click completes (unlike :active, which
   only applies during the mouse-down instant). */
.menu-tabs__tab:hover,
.menu-tabs__tab:active,
.menu-tabs__tab:focus {
    background: none;
}

.menu-tabs__tab:hover,
.menu-tabs__tab:active {
    color: var(--color-primary);
}

.menu-tabs__tab:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
    color: var(--color-primary);
}

.menu-tabs__tab.is-active {
    color: var(--color-text-dark);
    font-weight: 600;
}

/* A single shared sliding indicator (not a per-tab border) so it can animate
   between tabs — positioned/sized via assets/js/menu-tabs.js, since it needs
   each tab's actual rendered offset/width. No `transition` until JS adds
   .is-ready (after the first, instant positioning on page load), so it
   doesn't visibly slide in from the left on every page load — only on
   subsequent tab clicks. */
.menu-tabs__indicator {
    position: absolute;
    bottom: -1px;
    left: 0;
    height: 2px;
    background: var(--color-text-dark);
}

.menu-tabs__indicator.is-ready {
    transition: left 0.25s ease, width 0.25s ease;
}

.menu-panel {
    display: none;
}

.menu-panel.is-active {
    display: block;
}

.menu-item {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 1rem;
    padding-bottom: 1rem;
    margin-bottom: 1rem;
    border-bottom: 1px dashed rgba(63, 42, 29, 0.16);
}

.menu-item:last-child {
    border-bottom: none;
    margin-bottom: 0;
    padding-bottom: 0;
}

.menu-item__text {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.menu-item__name {
    color: var(--color-text-dark);
    font-weight: 600;
}

.menu-item__description {
    color: var(--color-text-light);
    font-size: 0.9rem;
}

.menu-item__price {
    color: var(--color-text-dark);
    font-weight: 600;
    white-space: nowrap;
}

@media (max-width: 1024px) {
    .single-shop__layout {
        grid-template-columns: 1fr;
    }
    .single-shop__hero {
        aspect-ratio: 30 / 15;
    }

    .single-shop__sidebar {
        position: static;
    }
}

/* ==========================
   PHOTO GALLERY
   A 3-column "masonry" grid (per the user's request — replaces an earlier
   2-column bento pass, see CHANGELOG for that whole iteration) + a
   hand-rolled lightbox (assets/js/gallery-lightbox.js) — deliberately
   minimal rather than pulling in a lightbox library for something this
   contained. Grid thumbnails use 'medium_large' (this theme's only
   front-end image size); the lightbox opens the original 'full' size,
   which after the site's upload pipeline is already capped at 1600px/WebP,
   so it's a genuine "bigger/crisper" view without a new registered size.

   Two separate tier-driven caps (see inc/gallery.php): how many photos get
   their own TILE (.single-shop__gallery-grid--count-N below — 3 for basic,
   5 for upgraded, so this grid never needs more than 5 columns worth of
   named areas), and how many are reachable AT ALL via the lightbox (3 for
   basic — same as the tile count, nothing more is ever reachable; 8 for
   upgraded, so the 5th tile gets a "+N" overlay opening the remaining 3
   through the lightbox). Same idea as Airbnb/Google's photo grids — never
   truly hidden, just not individually tiled past the display limit.

   Height is capped at one viewport (min(100vh, 640px) — the 640px ceiling
   keeps it from becoming enormous on very tall/large monitors, since
   100vh alone would scale without bound) instead of being driven by each
   tile's own aspect-ratio like the previous pass — cells fill whatever
   height the grid's row tracks resolve to, and img { object-fit: cover }
   below crops to fit rather than dictating the tile's height itself.

   Layout varies by how many photos actually get tiled (1-5, see above) —
   a shop with only 1-2 photos gets a simple single-row layout instead of a
   mostly-empty grid; counts 4-5 use one tall anchor tile on the left with
   the rest stacked in the remaining two columns. */

.single-shop__gallery-grid {
    display: grid;
    gap: 1rem;
    margin-top: 1rem;
    height: min(100vh, 640px);
}

.single-shop__gallery-grid--count-1 {
    grid-template-columns: 1fr;
}

.single-shop__gallery-grid--count-2 {
    grid-template-columns: 1fr 1fr;
}

.single-shop__gallery-grid--count-3 {
    grid-template-columns: 1fr 1fr 1fr;
}

.single-shop__gallery-grid--count-4 {
    grid-template-columns: 1fr 1fr 1fr;
    grid-template-rows: 1fr 1fr;
    grid-template-areas: "a b c" "a d d";
}

.single-shop__gallery-grid--count-5 {
    grid-template-columns: 1fr 1fr 1fr;
    grid-template-rows: 1fr 1fr;
    grid-template-areas: "a b d" "a c e";
}

.single-shop__gallery-grid--count-4 .single-shop__gallery-thumb:nth-child(1),
.single-shop__gallery-grid--count-5 .single-shop__gallery-thumb:nth-child(1) {
    grid-area: a;
}

.single-shop__gallery-grid--count-4 .single-shop__gallery-thumb:nth-child(2),
.single-shop__gallery-grid--count-5 .single-shop__gallery-thumb:nth-child(2) {
    grid-area: b;
}

.single-shop__gallery-grid--count-4 .single-shop__gallery-thumb:nth-child(3),
.single-shop__gallery-grid--count-5 .single-shop__gallery-thumb:nth-child(3) {
    grid-area: c;
}

.single-shop__gallery-grid--count-4 .single-shop__gallery-thumb:nth-child(4) {
    grid-area: d;
}

.single-shop__gallery-grid--count-5 .single-shop__gallery-thumb:nth-child(4) {
    grid-area: d;
}

.single-shop__gallery-grid--count-5 .single-shop__gallery-thumb:nth-child(5) {
    grid-area: e;
}

/* 3 columns of photos read as cramped slivers on a phone-width screen, so
   mobile falls back to a simpler 2-column flow instead of trying to force
   the same masonry areas into a narrow viewport. Clearing
   grid-template-areas alone isn't enough — the count-4/5 thumbs still carry
   an unconditional grid-area (a/b/c/d/e) from the rules above, and a
   grid-area referencing a name that no longer exists in
   grid-template-areas doesn't reliably fall back to auto-placement, so
   every tile was landing in the same cell. Explicitly resetting grid-area
   to auto is what actually makes them flow into separate cells — but that
   reset has to match the same :nth-child specificity as the rules it's
   overriding (0,3,0), not just the two classes alone (0,2,0), or those
   higher-specificity unconditional rules keep winning regardless of media
   query or source order. The 100vh cap is dropped too, since a
   fixed-height grid fighting a phone's limited vertical space is worse
   than just letting it size to its content there. */
@media (max-width: 640px) {
    .single-shop__hero {
        aspect-ratio: 30 / 15;
    }
    .single-shop__gallery-grid {
        height: auto;
        grid-template-columns: 1fr 1fr;
        grid-template-rows: none;
        grid-template-areas: none;
    }

    .single-shop__gallery-grid--count-4 .single-shop__gallery-thumb:nth-child(1),
    .single-shop__gallery-grid--count-4 .single-shop__gallery-thumb:nth-child(2),
    .single-shop__gallery-grid--count-4 .single-shop__gallery-thumb:nth-child(3),
    .single-shop__gallery-grid--count-4 .single-shop__gallery-thumb:nth-child(4),
    .single-shop__gallery-grid--count-5 .single-shop__gallery-thumb:nth-child(1),
    .single-shop__gallery-grid--count-5 .single-shop__gallery-thumb:nth-child(2),
    .single-shop__gallery-grid--count-5 .single-shop__gallery-thumb:nth-child(3),
    .single-shop__gallery-grid--count-5 .single-shop__gallery-thumb:nth-child(4),
    .single-shop__gallery-grid--count-5 .single-shop__gallery-thumb:nth-child(5) {
        grid-area: auto;
    }

    .single-shop__gallery-grid--count-1 {
        grid-template-columns: 1fr;
    }

    .single-shop__gallery-thumb {
        aspect-ratio: 1 / 1;
    }

    .single-shop__gallery-grid--count-1 .single-shop__gallery-thumb {
        aspect-ratio: 16 / 9;
    }
}

.single-shop__gallery-thumb {
    position: relative;
    -webkit-appearance: none;
    appearance: none;
    padding: 0;
    border: none;
    background: none;
    cursor: pointer;
    border-radius: var(--radius-md);
    overflow: hidden;
}

.single-shop__gallery-thumb img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.2s ease;
}

.single-shop__gallery-thumb:hover img,
.single-shop__gallery-thumb:focus-visible img {
    transform: scale(1.05);
}

.single-shop__gallery-thumb:focus-visible {
    outline: 2px solid var(--color-accent);
    outline-offset: 2px;
}

.single-shop__gallery-more {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(20, 12, 8, 0.55);
    color: #fff;
    font-family: var(--font-primary);
    font-size: 1.5rem;
    font-weight: 700;
}

.single-shop__lightbox {
    position: fixed;
    inset: 0;
    background: rgba(20, 12, 8, 0.92);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 1000;
}

.single-shop__lightbox[hidden] {
    display: none;
}

.single-shop__lightbox-img {
    max-width: min(90vw, 1100px);
    max-height: 85vh;
    border-radius: var(--radius-md);
    object-fit: contain;
}

.single-shop__lightbox-close,
.single-shop__lightbox-nav {
    -webkit-appearance: none;
    appearance: none;
    position: absolute;
    border: none;
    background: rgba(255, 255, 255, 0.12);
    color: #fff;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    transition: background 0.2s ease;
}

.single-shop__lightbox-close:hover,
.single-shop__lightbox-nav:hover {
    background: rgba(255, 255, 255, 0.24);
}

.single-shop__lightbox-close {
    top: 1.5rem;
    right: 1.5rem;
    width: 2.5rem;
    height: 2.5rem;
    font-size: 1.5rem;
    line-height: 1;
}

.single-shop__lightbox-nav {
    top: 50%;
    transform: translateY(-50%);
    width: 3rem;
    height: 3rem;
    font-size: 1.75rem;
    line-height: 1;
}

.single-shop__lightbox-prev {
    left: 1.5rem;
}

.single-shop__lightbox-next {
    right: 1.5rem;
}

body.single-shop__lightbox-open {
    overflow: hidden;
}

@media (max-width: 480px) {
    .single-shop__gallery-grid {
        grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
    }

    .single-shop__lightbox-nav {
        width: 2.25rem;
        height: 2.25rem;
        font-size: 1.25rem;
    }
}
