/* ============================================================================
   Theme Park Foodie — Design System
   Mobile-first, matching Figma designs

   DESIGN TOKENS
   ----------------------------------------------------------------------------
   border-radius: use only var(--radius) / var(--radius-card) /
   var(--radius-lg) / 999px (pill) / 50% (circle). The remaining 1px and
   2px usages are decorative line-caps on hamburger-icon spans (not
   corner rounding) — intentional exceptions.

   breakpoints: dominant pair is max:768 / min:769 (≈34 rules each).
   Secondary brackets at 600 (mobile/tablet) and 480 (small mobile).
   Additional values (601, 640, 641, 700, 901, 960, 1024) survive as
   component-specific tunings. A full consolidation to 3-4 named
   breakpoints is deferred — needs cross-page responsive regression
   testing on every layout before normalization, scope beyond #157.
   ----------------------------------------------------------------------------

   TABLE OF CONTENTS
   ----------------------------------------------------------------------------
   FOUNDATIONS
     Variables ............................................. ~line   8
     Reset (box-sizing, margin/padding) .................... ~line  66
     Site chrome (header, nav, footer) ..................... ~line 112
     Buttons (.btn, .btn-primary, .btn-outline, .btn-sm) ... ~line 360
     Section headings + utility tiles ...................... ~line 410
     Reusable cards (.page-heading-card) ................... ~line 485
     Entity tile (listing rows) ............................ ~line 590
     Restaurant grid + cards ............................... ~line 690
     Badges (.badge-service/cuisine/price) ................. ~line 870
     Prix-fixe / buffet menu layout (#97) .................. ~line 915

   ITEMS + MENU PRIMITIVES
     Menu items shared chrome .............................. ~line 1245
     List-add button (+ list picker popover) ............... ~line 1310

   PAGE: SEARCH
     Search page + suggestions ............................. ~line 1410

   PAGE: PROFILE / SETTINGS
     User profile + activity ............................... ~line 4400
     Settings page ......................................... ~line 4320

   PAGE: REVIEWS form components
     Yes/no toggle, score boxes, prompt chips .............. ~line 3895

   PAGE: HOMEPAGE
     Hero, browse-by-park, popular rails, articles ......... ~line 2090

   PAGE: RESTAURANT DETAIL (#106 redesign)
     Stars + .btn-external utility ......................... ~line 5215
     Header card ........................................... ~line 5260
     Photo carousel (Option D count-aware grid) ............ ~line 5360
     Shared section chrome ................................. ~line 5450
     Popular Items row ..................................... ~line 5480
     Review chip picker + review cards ..................... ~line 5530
     Related links ......................................... ~line 5705
     Mobile breakpoints .................................... ~line 5720

   PAGE: MENU (#99 Option B — mirror Disney sections)
     Toolbar (meal entry + view controls) .................. ~line 5820
     Filter panel .......................................... ~line 5960
     Top Rated carousel .................................... ~line 5990
     Sub-section accordions ................................ ~line 6065
     Item cards (thumb / main / side) ...................... ~line 6125
     Thumbs-up % badge + Rate it pill ...................... ~line 6245
     Pricing banner (prix-fixe / buffet) ................... ~line 6325
     Mobile breakpoints .................................... ~line 6295

   PAGE: BLOG
     Blog index, post layout, sidebar ...................... ~line 4840

   MOBILE OVERRIDES (≤480px) ............................... ~line 4770
   FLASH messages, error banners ........................... ~line 1975
   AUTH modals ............................................. ~line 2835
   ADMIN tooling (admin-page-header, admin-table) .......... www/css/admin.css
   ============================================================================ */

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* ---------------------------------------------------------------------------
   Variables
   --------------------------------------------------------------------------- */
:root {
    /* Brand — TPF Brand Guide / UI & Homepage Design Guide.
       Coral is the primary accent, navy carries headings + chrome,
       warm cream is the body surface, gold is the editorial sparkle
       accent, neutral pairs with cream for borders/dividers. */
    --color-primary: #FF5A47;
    --color-primary-dark: #E04332;
    --color-primary-light: #FF7868;
    --color-primary-tint: rgba(255, 90, 71, 0.12);

    /* Chrome */
    --color-header: #0D2B52;
    --color-footer: #0D2B52;

    /* Neutral */
    --color-bg: #F8F3EC;
    --color-bg-light: #FFFFFF;
    --color-text: #1F2937;
    --color-text-light: #6B7280;
    --color-border: #E8E3DC;
    --color-white: #FFFFFF;

    /* Scores */
    --color-score-green: #4CAF50;
    --color-score-yellow-green: #8BC34A;
    --color-score-yellow: #FFC107;
    --color-score-orange: #FF9800;
    --color-score-red: #F44336;

    /* Feedback */
    --color-success: #2E7D32;
    --color-error: #C62828;

    /* Secondary CTA (editorial gold accent) */
    --color-secondary: #F5C14E;

    /* Layout */
    --max-width: 480px;
    --max-width-wide: 1100px;
    --font-family: 'DM Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    --font-family-heading: 'Outfit', 'DM Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    --radius: 6px;
    --radius-lg: 12px;
    --shadow: 0 1px 3px rgba(13, 43, 82, 0.06), 0 1px 2px rgba(13, 43, 82, 0.05);
    --shadow-hover: 0 6px 18px rgba(13, 43, 82, 0.10);

    /* Card design tokens — flat-bordered canonical (post-#99/#106
       cleanup). Use these on any container that needs the standard
       card chrome so the radius/border stays consistent. */
    --radius-card: 10px;
    --card-border: 1px solid var(--color-border);
}

/* Headings use the editorial display face. */
h1, h2, h3, h4, h5, h6 {
    font-family: var(--font-family-heading);
    color: var(--color-header);
    line-height: 1.2;
}

html {
    font-size: 16px;
    /* scroll-padding-top reserves space at the top of the viewport
       when the browser (or JS scrollIntoView()) auto-scrolls to an
       anchor. Without it, hash-jumps land under the sticky
       .site-header and the actual target is hidden — e.g. mobile
       guests tapping "Leave a Review" couldn't see the star
       picker. Tuned to the header height per breakpoint. */
    scroll-padding-top: 64px;
}
@media (min-width: 601px) {
    html { scroll-padding-top: 88px; }
}
body {
    font-family: var(--font-family);
    color: var(--color-text);
    background: var(--color-bg);
    line-height: 1.6;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    /* Stop the hero collage's intentionally-overflowing photos and
       decorations from creating a horizontal scrollbar on mobile, where
       the content container fills the viewport. Desktop has whitespace
       margins so nothing actually visible gets clipped. */
    overflow-x: hidden;
}

a { color: var(--color-primary); text-decoration: none; }
a:hover { color: var(--color-primary-dark); }

.btn-admin-edit {
    display: block;
    text-align: center;
    width: fit-content;
    margin-left: auto;
    padding: 4px 12px;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--color-white);
    background: #7B1FA2;
    border-radius: var(--radius);
    margin-bottom: 8px;
    text-decoration: none;
}
.btn-admin-edit:hover {
    background: #6A1B9A;
    color: var(--color-white);
}

img { max-width: 100%; height: auto; }

/* ---------------------------------------------------------------------------
   Header
   --------------------------------------------------------------------------- */
.site-header {
    position: sticky;
    top: 0;
    z-index: 100;
}

.header-accent {
    height: 4px;
    background: var(--color-primary);
}

.env-banner {
    background: repeating-linear-gradient(
        135deg,
        #facc15 0,
        #facc15 16px,
        #1f2937 16px,
        #1f2937 32px
    );
    color: var(--color-white);
    text-align: center;
    font-size: 11px;
    font-weight: 800;
    letter-spacing: 0.15em;
    padding: 4px 8px;
    text-shadow: 0 1px 0 rgba(0, 0, 0, 0.6);
}

.header-bar {
    background: var(--color-white);
    border-bottom: 1px solid var(--color-border);
    padding: 14px 16px;
}

.header-container {
    max-width: var(--max-width-wide);
    margin: 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
}

.header-logo {
    display: flex;
    align-items: center;
    text-decoration: none;
}

.header-logo img {
    display: block;
    height: 48px;
    width: auto;
}

/* Tighten the sticky header on phones so it doesn't eat the top of
   every page. ~30% shorter — logo shrinks to 36px and header-bar
   padding drops from 14px/16px to 8px/12px. The resort-switcher
   stays visible since most phones can fit it next to the smaller
   logo; if it ever crowds out, hide it behind the hamburger. (#132 A2) */
@media (max-width: 600px) {
    .header-bar {
        padding: 8px 12px;
    }
    .header-container {
        gap: 8px;
    }
    .header-logo img {
        height: 36px;
    }
}
/* iPhone SE / very narrow phones — shrink the resort-switcher
   typography so logo + switcher + hamburger fit on 320px without
   wrapping. (#132 C) */
@media (max-width: 380px) {
    .resort-toggle {
        padding: 3px 9px;
        font-size: 0.7rem;
    }
    .resort-switcher {
        margin-right: 0;
    }
}

/* Resort switcher — neutral cream pill that flips coral when active. */
.resort-switcher {
    display: flex;
    align-items: center;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: 999px;
    overflow: hidden;
    margin-right: 8px;
}
.resort-toggle {
    padding: 4px 12px;
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--color-text-light);
    text-decoration: none;
    transition: background 0.15s, color 0.15s;
    letter-spacing: 0.03em;
}
.resort-toggle:hover {
    color: var(--color-header);
    text-decoration: none;
}
.resort-toggle.active {
    background: var(--color-primary);
    color: var(--color-white);
}
.desktop-nav {
    display: none;
    align-items: center;
    gap: 24px;
}
.desktop-nav a {
    color: var(--color-header);
    font-family: var(--font-family-heading);
    font-size: 0.95rem;
    font-weight: 500;
    text-decoration: none;
    transition: color 0.15s;
}
.desktop-nav a:hover {
    color: var(--color-primary);
    text-decoration: none;
}
/* Highlight the primary auth CTA in the desktop nav as a coral pill. */
.desktop-nav a.header-cta {
    background: var(--color-primary);
    color: var(--color-white);
    padding: 8px 18px;
    border-radius: 999px;
    font-weight: 600;
    transition: background 0.15s;
}
.desktop-nav a.header-cta:hover {
    background: var(--color-primary-dark);
    color: var(--color-white);
}

@media (min-width: 769px) {
    .desktop-nav { display: flex; }
    .header-hamburger { display: none !important; }
    .search-menu-icon { display: none !important; }
    .mobile-nav { display: none !important; }
}

.header-hamburger {
    background: none;
    border: none;
    cursor: pointer;
    padding: 8px;
    display: flex;
    flex-direction: column;
    gap: 5px;
}
.header-hamburger span {
    display: block;
    width: 24px;
    height: 3px;
    background: var(--color-header);
    border-radius: 2px;
    transition: transform 0.2s, opacity 0.2s;
}

/* Search bar section */
.search-bar-section {
    background: var(--color-white);
    border-bottom: 1px solid var(--color-border);
    padding: 12px 16px;
}

.search-container {
    max-width: var(--max-width-wide);
    margin: 0 auto;
    display: flex;
    align-items: center;
    gap: 12px;
}

.search-menu-icon {
    background: none;
    border: none;
    cursor: pointer;
    padding: 8px;
    display: flex;
    flex-direction: column;
    gap: 4px;
    flex-shrink: 0;
}
.search-menu-icon span {
    display: block;
    width: 20px;
    height: 2px;
    background: var(--color-text);
    border-radius: 1px;
}

.search-form-inline {
    display: flex;
    flex: 1;
    min-width: 0;
}

.search-input {
    flex: 1;
    padding: 10px 14px;
    border: 1px solid var(--color-border);
    border-right: none;
    border-radius: var(--radius) 0 0 var(--radius);
    font-size: 16px;
    font-family: var(--font-family);
    color: var(--color-text);
    min-width: 0;
}
.search-input::placeholder { color: #BDBDBD; }
.search-input:focus { outline: none; border-color: var(--color-primary); }

.search-btn {
    background: var(--color-primary);
    color: var(--color-white);
    border: none;
    padding: 10px 16px;
    border-radius: 0 var(--radius) var(--radius) 0;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    transition: background 0.15s;
}
.search-btn:hover { background: var(--color-primary-dark); }

/* Mobile nav overlay */
.mobile-nav {
    display: none;
    flex-direction: column;
    background: var(--color-header);
    padding: 0 16px 16px;
}
.mobile-nav.open { display: flex; }
.mobile-nav a {
    color: var(--color-white);
    padding: 10px 0;
    font-weight: 500;
    font-size: 0.95rem;
    border-bottom: 1px solid rgba(255,255,255,0.1);
}
.mobile-nav a:last-child { border-bottom: none; }
.mobile-nav a:hover { color: var(--color-primary-light); }

/* ---------------------------------------------------------------------------
   Main Content
   --------------------------------------------------------------------------- */
.site-main { flex: 1; }

/* Mobile-first: minimal horizontal padding on phones so card images
   + chips fill more of the screen. Desktop bumps it back up for
   editorial breathing room. (#136) */
.content-container {
    max-width: var(--max-width-wide);
    margin: 0 auto;
    padding: 10px 8px;
}
@media (min-width: 600px) {
    .content-container {
        padding: 16px 12px;
    }
}
@media (min-width: 1024px) {
    .content-container {
        padding: 24px 16px;
    }
}
/* When breadcrumbs lead the container, trim the top padding so the
   container-pad-top + breadcrumbs margin-bottom asymmetry evens
   out — visually centres the breadcrumbs in the vertical space
   around them (Brandon 2026-06-19). */
@media (min-width: 600px) {
    .content-container:has(> .breadcrumbs:first-child),
    .content-container:has(> .breadcrumbs-with-chips:first-child) {
        padding-top: 12px;
    }
}

/* ---------------------------------------------------------------------------
   Hero Section
   --------------------------------------------------------------------------- */
/* Hero action row — used inside page-heading-card-hero on 404/error
   pages and inside .home-hero. Column-stack centered. */
.hero-actions {
    display: flex;
    flex-direction: column;
    gap: 12px;
    align-items: center;
}

/* ---------------------------------------------------------------------------
   Buttons
   --------------------------------------------------------------------------- */
.btn {
    display: inline-block;
    padding: 14px 28px;
    /* Transparent 2px border so .btn-primary and .btn-outline both
       render at the same total size — variants only swap the border
       color rather than redefining padding. */
    border: 2px solid transparent;
    border-radius: 999px;
    font-family: var(--font-family-heading);
    font-weight: 600;
    font-size: 0.95rem;
    cursor: pointer;
    text-align: center;
    transition: background 0.15s, transform 0.1s, border-color 0.15s, color 0.15s;
    text-decoration: none;
}
.btn:hover { text-decoration: none; }
.btn:active { transform: scale(0.98); }

.btn-primary {
    background: var(--color-primary);
    color: var(--color-white);
}
.btn-primary:hover { background: var(--color-primary-dark); color: var(--color-white); }

.btn-secondary {
    background: var(--color-secondary);
    color: var(--color-header);
}
.btn-secondary:hover { background: #E0AC32; color: var(--color-header); }

/* Secondary CTA per brand guide — white bg, navy border + text.
   Inherits .btn padding (the transparent border on .btn reserves
   the 2px that the visible border takes here). */
.btn-outline {
    background: var(--color-white);
    border-color: var(--color-header);
    color: var(--color-header);
}
.btn-outline:hover {
    background: var(--color-header);
    color: var(--color-white);
}

.btn-block { width: 100%; max-width: 380px; }
.btn-sm { padding: 8px 16px; font-size: 0.875rem; }

/* ---------------------------------------------------------------------------
   Section Headings
   --------------------------------------------------------------------------- */
.section-title {
    font-size: 1.35rem;
    font-weight: 600;
    color: var(--color-text);
    text-align: center;
    margin-bottom: 12px;
}

.section-subtitle {
    color: var(--color-text-light);
    text-align: center;
    margin-bottom: 16px;
}

/* ---------------------------------------------------------------------------
   Category / Image Grid (circular items)
   --------------------------------------------------------------------------- */
.category-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 12px;
    padding: 20px 16px;
}
.category-item {
    aspect-ratio: 1;
    background: #D3D3D3;
    border-radius: var(--radius);
}

.circle-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 20px;
    max-width: 320px;
    margin: 0 auto;
    padding: 0 16px;
}
.circle-item {
    aspect-ratio: 1;
    background: #D3D3D3;
    border-radius: 50%;
}

/* ---------------------------------------------------------------------------
   Featured / Content Cards
   --------------------------------------------------------------------------- */
.featured-image {
    width: 100%;
    aspect-ratio: 16/9;
    background: #D3D3D3;
    border-radius: var(--radius);
}

/* Testimonial — quote card with a primary-color accent stripe on
   the left, matching the rest of the card language. */
.testimonial-card {
    margin: 0;
    padding: 18px 20px;
    background: var(--color-white);
    border-radius: var(--radius-lg);
    border-left: 4px solid var(--color-primary);
    box-shadow: var(--shadow);
    color: var(--color-text);
}
.testimonial-text {
    font-size: 1rem;
    line-height: 1.55;
    font-style: italic;
    margin: 0 0 8px;
}
.testimonial-author {
    font-size: 0.9rem;
    color: var(--color-text-light);
}

/* ---------------------------------------------------------------------------
   Reusable page + section heading cards (#36 design language extension)
   --------------------------------------------------------------------------- */
/* ===========================================================
   Top-of-page heading patterns — TWO distinct primitives, kept
   separate intentionally (Brandon 2026-06-21):

   .page-heading-card  — centered title + subtitle in a white
                         card. Used by listing/index pages
                         (parks, lists, /search, blog index,
                         contact, full menu).

   .detail-header      — two-column white card with identity
                         (name + bookmark + meta) on the left
                         and rating + CTA stack on the right.
                         Used by entity detail pages
                         (restaurant, menu item). Named
                         "detail-" rather than "restaurant-"
                         because the menu-item page uses it too.
   =========================================================== */
/* Mobile-first: 4px top margin, 8px bottom (was 8/16). Padding
   tightens further at <600px via the existing media query below.
   Desktop bumps both back up. (#136) */
.page-heading-card {
    position: relative;
    margin: 4px 0 8px;
    padding: 14px 48px 10px;
    text-align: center;
    background: var(--color-white);
    border: var(--card-border);
    border-radius: var(--radius-card);
    border-top: 4px solid var(--color-primary);
}
@media (min-width: 769px) {
    .page-heading-card {
        margin: 8px 0 16px;
        padding: 18px 56px 14px;
    }
}
/* Score badge top-left, save button top-right — mirrors the restaurant
   summary treatment so the H1 stays centered as actions appear. */
.page-heading-card-score {
    position: absolute;
    top: 12px;
    left: 12px;
    font-size: 1rem;
    padding: 4px 10px;
}
.page-heading-card > .btn-list-add {
    position: absolute;
    top: 10px;
    right: 12px;
}
.page-heading-card-title h1 {
    font-size: 1.9rem;
    font-weight: 700;
    letter-spacing: -0.01em;
    line-height: 1.15;
    margin: 0;
    color: var(--color-header);
}
.page-heading-card-subtitle {
    margin: 4px 0 0;
    color: var(--color-text-light);
    font-size: 0.95rem;
}

/* Mobile: tighten the heading card so it doesn't eat the top of every
   page. Smaller H1, less padding — leaves room for the search bar and
   filter chips below the fold without an extra scroll. Horizontal
   padding dropped from 48px → 16px so the heading reads with the
   tight mobile gutter the rest of the site uses (Brandon 2026-06-26).
   The 16px still leaves room for the absolutely-positioned
   .btn-list-add (right:12px) and .page-heading-card-score (left:12px)
   to clear the title. (#132 A4) */
@media (max-width: 600px) {
    .page-heading-card {
        margin: 4px 0 8px;
        padding: 10px 16px 10px;
    }
    .page-heading-card-title h1 {
        font-size: 1.4rem;
        line-height: 1.2;
    }
    .page-heading-card-subtitle {
        font-size: 0.85rem;
    }
}

/* Hero variant of the heading card — larger type and CTA-friendly. */
.page-heading-card-hero {
    padding: 36px 24px 28px;
    margin-top: 16px;
}
.page-heading-card-hero .page-heading-card-title h1 {
    font-size: 2.1rem;
    line-height: 1.18;
}
.page-heading-card-hero .page-heading-card-subtitle {
    font-size: 1rem;
    line-height: 1.55;
    max-width: 420px;
    margin-left: auto;
    margin-right: auto;
}
.page-heading-card-hero .hero-actions {
    margin-top: 20px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
}
.page-heading-card-hero .login-note {
    font-size: 0.85rem;
    color: var(--color-text-light);
    margin: 0;
}

/* Lighter visual weight than the page heading — a centered subsection
   title with a primary-color underline accent. Anchors a group of
   tiles below it without competing with the page heading. */
/* Mobile-first: tight gap before the heading; desktop adds more
   breathing room. (#136) */
.section-heading-card {
    position: relative;
    margin: 8px 0 6px;
    padding-bottom: 4px;
    font-size: 1.1rem;
    font-weight: 600;
    text-align: center;
    color: var(--color-header);
}
@media (min-width: 769px) {
    .section-heading-card {
        margin: 16px 0 10px;
        font-size: 1.15rem;
    }
}
.section-heading-card::after {
    content: '';
    display: block;
    width: 40px;
    height: 3px;
    margin: 6px auto 0;
    background: var(--color-primary);
    border-radius: 2px;
}
.section-heading-count {
    font-weight: 400;
    color: var(--color-text-light);
    font-size: 0.9rem;
    margin-left: 4px;
}
/* When a section heading carries an inline "Sorted by X" caption
   to its right, switch the heading from centered to a 2-column
   row so both pieces sit on the same line. The default centered
   variant is preserved for headings that don't need this signal
   (Brandon 2026-06-23). */
.section-heading-with-sort {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    text-align: left;
    flex-wrap: wrap;
}
.section-heading-with-sort::after {
    display: none;
}
.section-heading-sort {
    font-weight: 400;
    color: var(--color-text-light);
    font-size: 0.85rem;
}
@media (max-width: 480px) {
    .section-heading-sort {
        font-size: 0.78rem;
    }
}

/* ---------------------------------------------------------------------------
   Entity tile — shared compact-row layout for parks, restaurants, and
   menu items across the search, list, park, and homepage surfaces.
   Three-column flexbox layout (#108):
     [ thumb (LEFT, 72px) ] [ body (name + meta + tags) ] [ score (RIGHT) ]
   Aligning thumb-left / score-right matches the restaurant detail
   header so listing tiles read consistently with the page they link to.
   Thumb and score columns are both optional — body fills the row when
   either is absent.
   --------------------------------------------------------------------------- */
.entity-tile-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-bottom: 16px;
}
/* Multi-column tile grid variant for homepage-style sections where we
   want to show several entity tiles side-by-side on wider viewports. */
.entity-tile-list-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 8px;
}
@media (min-width: 640px) {
    .entity-tile-list-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}
@media (min-width: 960px) {
    .entity-tile-list-grid {
        grid-template-columns: repeat(3, 1fr);
    }
}
/* Card height matches the thumb width so the thumb is a clean
   square. Title is truncated to 1 line; meta and tags below.
   Rating column sits in the bottom-right corner — numeric over
   stars. (#136) */
.entity-tile {
    position: relative;
    display: flex;
    align-items: stretch;
    gap: 0;
    padding: 0;
    height: 88px;
    background: var(--color-white);
    border: var(--card-border);
    border-radius: var(--radius-card);
    color: var(--color-text);
    text-decoration: none;
    overflow: hidden;
    transition: border-color 0.2s, background 0.2s;
}
@media (min-width: 769px) {
    .entity-tile {
        height: 96px;
    }
}
.entity-tile:hover {
    border-color: var(--color-primary);
    text-decoration: none;
    color: var(--color-text);
}
/* Body: title → meta → tags top-aligned with uniform 4px gaps.
   Rating sits inline at the right of the meta + tags rows on
   venue cards (#147 round 2), so the body owns the full card
   width after the thumb and the right padding holds the rating
   against the right edge. */
.entity-tile-body {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    padding: 8px 10px;
}
/* Two-column rows inside the body — left content (meta / tags)
   on the left, right content (numeric / stars) on the right.
   min-height keeps the row from collapsing when one side is
   empty (e.g. item card with no dietary tags + a short price),
   so item + venue tiles share the same total body height instead
   of items drifting downward via justify-content: center
   (Brandon 2026-06-20). */
.entity-tile-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    min-width: 0;
    min-height: 22px;
}
.entity-tile-row > .entity-tile-meta,
.entity-tile-row > .entity-tile-tags,
.entity-tile-row > .entity-tile-description {
    flex: 1 1 auto;
    min-width: 0;
}
/* Numeric + stars + price + thumbs-badge sit on the right side of
   the meta and tags rows. They're sized to match the body text
   (~0.8rem) so they don't dominate row height and force the tile
   to feel cramped (Brandon 2026-06-20). */
.entity-tile-score-numeric {
    flex: 0 0 auto;
    font-size: 0.85rem;
    font-weight: 700;
    color: var(--color-header);
    line-height: 1;
    font-variant-numeric: tabular-nums;
}
/* Sample-size suffix (#340). Sits inline INSIDE the <strong> so
   the "· 12 reviews" hugs the numeric with just this margin —
   outside the strong it was inheriting an 8px flex gap and reading
   too far apart. Muted + lighter weight keeps the numeric primary
   (Brandon 2026-07-15 spacing tighten). */
.entity-tile-score-count {
    margin-left: 3px;
    font-size: 0.78rem;
    font-weight: 500;
    color: var(--color-text-light);
    font-variant-numeric: tabular-nums;
}
.entity-tile-tags-row .stars {
    flex: 0 0 auto;
}
/* Menu-item rating pill (+ owner label) responsive slot (Brandon
   2026-07-15). Rendered in two DOM sites — meta row + tags row —
   with CSS toggling visibility per breakpoint.
     Mobile default: pill shows in tags row (left-anchored) so
       vote counts form a vertical spine down the grid.
     Desktop (>= 769px): pill shows in meta row (right-anchored)
       where it sat originally, freeing the tags row for tags +
       coin + price. */
.entity-tile-rating-slot {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex: 0 0 auto;
}
.entity-tile-meta-row .entity-tile-rating-slot {
    display: none;
}
.entity-tile-tags-row .entity-tile-rating-slot {
    display: inline-flex;
}
@media (min-width: 769px) {
    .entity-tile-meta-row .entity-tile-rating-slot {
        display: inline-flex;
    }
    .entity-tile-tags-row .entity-tile-rating-slot {
        display: none;
    }
}
/* Title row holds the title; bookmark moved to the thumb in #147
   item 5, so the title gets the full body width with no right-
   padding reservation. */
.entity-tile-title-row {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    padding-right: 0;
}
.entity-tile-title-row .entity-tile-title {
    margin: 0;
    min-width: 0;
    flex: 1 1 auto;
}
/* Menu-item price — sits on the right of the tags row. Sized
   just under the title and colored to match .menu-item-price on
   the menu page (`--color-primary-dark`) so prices read in the
   same brand-coral across surfaces (Brandon 2026-06-20). */
.entity-tile-price {
    flex: 0 0 auto;
    font-size: 0.9rem;
    font-weight: 700;
    color: var(--color-primary-dark);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    line-height: 1;
}
/* Title truncates to a single line with ellipsis so the card
   stays uniform height. (#136) */
.entity-tile-title {
    font-size: 0.95rem;
    font-weight: 700;
    margin: 0;
    line-height: 1.25;
    color: var(--color-header);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* Meta stays on a single line; truncates with ellipsis when body
   width can't fit the full "{area}, {park}" string. (#136) */
.entity-tile-meta {
    font-size: 0.78rem;
    color: var(--color-text-light);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    min-width: 0;
}
/* Description truncates to a single line — earlier 2-line clamp
   blew the card's fixed height when descriptions ran long, pushing
   content above the visible card edge (#147 item 4a). */
.entity-tile-description {
    font-size: 0.78rem;
    color: var(--color-text-light);
    line-height: 1.4;
    margin: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* Menu-item variant of the meta row: dietary icons lead, then
   restaurant · park text. The text span is the ellipsis target so
   icons stay visible regardless of card width. (#147 item 4d) */
.entity-tile-meta-with-icons {
    display: flex;
    align-items: center;
    min-width: 0;
    /* Override the base meta's whitespace rules so the flex layout
       handles truncation via the text span. */
    white-space: normal;
    overflow: visible;
}
.entity-tile-meta-icons {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 2px;
    margin-right: 4px;
}
.entity-tile-meta-text {
    flex: 1 1 auto;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.entity-tile-title .dietary-icon {
    font-size: 0.85rem;
    margin-left: 4px;
    vertical-align: middle;
}
.entity-tile-tags {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 4px;
}
/* Thumb sits flush with the card's left edge — no border-radius
   needed since the card's `overflow: hidden` clips against its
   own corners. Same vertical height as the card so it fills
   top-to-bottom. (#136) */
.entity-tile-thumb {
    position: relative;
    flex: 0 0 88px;
    width: 88px;
    align-self: stretch;
    overflow: hidden;
    background: var(--color-bg-light);
}
@media (min-width: 769px) {
    .entity-tile-thumb {
        flex: 0 0 96px;
        width: 96px;
    }
}
.entity-tile-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Placeholder thumb — camera silhouette on light-grey when no
   image exists. Keeps card layout uniform whether or not a photo
   is available. (#147 item 4c) */
/* hsl-letter placeholder. Background hue is set inline from
   renderTileThumb() (crc32 hash of the name), so each item keeps
   the same colour across surfaces. Reverted from a camera-
   silhouette SVG per Brandon's preference. */
.entity-tile-thumb-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
}
.entity-tile-thumb-letter {
    color: rgba(255, 255, 255, 0.92);
    font-size: 1.6rem;
    font-weight: 700;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
    line-height: 1;
}
/* Small white camera glyph on no-image placeholders (Brandon
   2026-06-20). Sized to ~30% of the 88/96px thumb so it reads as
   "image missing" without dominating the cell. */
.entity-tile-thumb-camera {
    width: 28px;
    height: 28px;
    color: rgba(255, 255, 255, 0.92);
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.15));
}

/* Bookmark overlay anchored to the thumb's top-right corner with a
   semi-translucent white circle backdrop so the icon reads against
   any image — light, dark, busy, or placeholder. (#147 item 5)
   Brandon 2026-06-19: 4px inset feels snug-in-the-corner without
   crowding the icon against the edge. */
.entity-tile-bookmark {
    position: absolute;
    top: 4px;
    right: 4px;
    z-index: 2;
    width: 28px;
    height: 28px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    background: rgba(255, 255, 255, 0.92);
    border: none;
    border-radius: 50%;
    color: var(--color-header);
    cursor: pointer;
    transition: background 0.15s ease, color 0.15s ease, transform 0.1s ease;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.18);
}
.entity-tile-bookmark:hover {
    background: var(--color-white);
    transform: scale(1.06);
}
.entity-tile-bookmark.in-list {
    background: var(--color-primary);
    color: var(--color-white);
}
.entity-tile-bookmark.in-list:hover {
    background: var(--color-primary);
}
/* Anonymous variant — same chrome but slightly muted so logged-in
   bookmarks still pop. Click opens the auth popup with a sign-up
   nudge (Brandon 2026-06-21 — was hidden entirely for signed-out
   visitors; the feature was invisible to first-time guests). */
.entity-tile-bookmark-anon {
    background: rgba(255, 255, 255, 0.85);
    color: var(--color-text-light);
}
.entity-tile-bookmark-anon:hover {
    background: var(--color-white);
    color: var(--color-header);
}
/* Score column — numeric stacked above stars, both right-
   aligned to the card's right edge and pushed to the bottom so
   they sit alongside the body's tags row. Min-width reserves
   the same horizontal real estate even when the venue has no
   rating yet, so the body's title-ellipsis truncates at the
   same character position across cards. (#136) */
.entity-tile-score {
    flex: 0 0 auto;
    min-width: 100px;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    justify-content: flex-end;
    padding: 8px 10px;
    gap: 2px;
}
/* Dead composition — neither renderVenueTile() in app/common.php
   nor any template emits .entity-tile-score .restaurant-card-score
   any more. Kept the parent .entity-tile-score above as it's still
   referenced by other compositions; this nested rule is dropped
   (#157 audit). */

/* Would-Order-Again tonal pill for menu-item cards (#147 item 4b).
   Tone bands come from thumbsTone() in app/common.php: green for
   85+, yellow-green for 75-84, yellow for 60-74, orange for 40-59,
   red for <40. Brandon 2026-06-22: YouTube-style pill — light grey
   rounded background with the thumbs-up + % inline, tone applies as
   text color so the signal still reads at a glance. The familiar
   chrome reuses the same visual language as YouTube's like pill. */
.thumbs-badge {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px 10px;
    background: #f1f3f4;
    border-radius: 999px;
    font-size: 0.9rem;
    font-weight: 700;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}
.thumbs-badge-icon {
    flex-shrink: 0;
    margin-top: -1px;
}
/* Sample-size disclosure inside the pill (#340). Slightly smaller
   + lighter weight than the % so the tone signal stays primary
   while the vote count is still readable at a glance. */
.thumbs-badge-count {
    margin-left: 2px;
    font-size: 0.78rem;
    font-weight: 500;
    opacity: 0.75;
}
.thumbs-badge-green        { color: #2e7d32; }
.thumbs-badge-yellow-green { color: #558b2f; }
.thumbs-badge-yellow       { color: #b26a00; }
.thumbs-badge-orange       { color: #d84315; }
.thumbs-badge-red          { color: #c62828; }
.thumbs-badge.is-unrated {
    color: var(--color-text-light);
    font-weight: 500;
}
/* Owner-rating attribution label (#331) — small "{Name}'s rating"
   caption that sits between the meta text and the score badge when
   a non-owner is viewing a creator's list. Small, muted, light-
   weight so it doesn't compete with the score chrome next to it —
   its only job is to disambiguate owner-sourced rows from the
   community fallback rows in the same list. */
.entity-tile-owner-rating-label {
    flex: 0 0 auto;
    font-size: 0.7rem;
    font-weight: 400;
    color: var(--color-text-light);
    line-height: 1;
    white-space: nowrap;
    margin-right: 6px;
    align-self: center;
}
/* Owner-view actions column (#111) — replaces .entity-tile-score on
   the owner's own list view. Stacks the rating cell + trash button
   in the same right-hand gutter the community score occupies on a
   non-owner view, so the row keeps the same column rhythm. */
.entity-tile-actions {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 0 10px 0 4px;
}
.entity-tile-rating {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 2px;
    font-size: 0.78rem;
    line-height: 1.1;
}
.entity-tile-rating-label {
    display: inline-block;
    font-size: 0.65rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-text-light);
    margin-right: 4px;
}
.entity-tile-rating-mine {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: var(--color-header);
}
.entity-tile-rating-community,
.entity-tile-rating-community-only {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: var(--color-text-light);
    font-size: 0.72rem;
}
.entity-tile-rate-cta {
    display: inline-flex;
    align-items: center;
    padding: 2px 8px;
    border: 1px solid var(--color-primary);
    color: var(--color-primary);
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.entity-tile-remove {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    padding: 0;
    background: transparent;
    border: 1px solid transparent;
    border-radius: var(--radius);
    color: var(--color-text-light);
    cursor: pointer;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.entity-tile-remove:hover,
.entity-tile-remove:focus-visible {
    background: var(--color-bg-light);
    color: #c0392b;
    border-color: #c0392b;
    outline: none;
}
/* Fade + collapse on remove. Driven by the JS handler in list.html. */
.entity-tile.entity-tile-removing,
.list-row.list-row-removing {
    opacity: 0;
    transform: translateX(8px);
    transition: opacity 0.22s ease-out, transform 0.22s ease-out;
    pointer-events: none;
}

/* List page row wrapper — positions the trash overlay over the
   shared entity-tile card so /lists reuses the same card design
   as /search + homepage rails (Brandon 2026-06-21). */
.list-row {
    position: relative;
}
.list-row-trash {
    position: absolute;
    top: 50%;
    right: 8px;
    transform: translateY(-50%);
    width: 32px;
    height: 32px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: none;
    background: rgba(255, 255, 255, 0.92);
    color: var(--color-text-light);
    border-radius: 50%;
    cursor: pointer;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.12);
    transition: background 0.15s, color 0.15s;
    z-index: 2;
}
.list-row-trash:hover {
    background: #fff;
    color: #c62828;
}
/* Narrow-phone tightening for the right-edge action elements so the
   body keeps room. Thumb stays at 88px from the default; body has
   ~225px on a 375px iPhone after content-container + card padding. */
@media (max-width: 480px) {
    .entity-tile-actions {
        gap: 4px;
    }
    .entity-tile-remove {
        width: 28px;
        height: 28px;
    }
}
@media (max-width: 400px) {
    .entity-tile-rating-community,
    .entity-tile-rating-community-only {
        display: none;
    }
}

/* ---------------------------------------------------------------------------
   Restaurant Grid & Cards
   --------------------------------------------------------------------------- */
.restaurant-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 12px;
    margin-bottom: 16px;
}
.restaurant-card {
    background: var(--color-white);
    border: var(--card-border);
    border-radius: var(--radius-card);
    padding: 16px;
    display: block;
    color: var(--color-text);
    transition: border-color 0.2s;
}
.restaurant-card.has-image {
    padding: 0;
    overflow: hidden;
}
.restaurant-card.has-image .restaurant-card-body {
    padding: 12px 16px 16px;
}
.restaurant-card-image {
    width: 100%;
    height: 140px;
    overflow: hidden;
}
.restaurant-card-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.restaurant-card:hover { border-color: var(--color-primary); text-decoration: none; }
.restaurant-card h3 { font-size: 1rem; margin-bottom: 4px; }

/* Photo Gallery */
.photo-gallery {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
    gap: 12px;
    margin-bottom: 16px;
}
.photo-gallery-item {
    position: relative;
    border-radius: var(--radius-lg);
    overflow: hidden;
    box-shadow: var(--shadow);
    background: var(--color-white);
}
.photo-gallery-item img {
    width: 100%;
    height: 150px;
    object-fit: cover;
    display: block;
}
/* Caption + by-credit text below the thumb retired (Brandon 2026-
   06-19) — credit now overlays the image as a camera-icon chip
   matching the carousel attribution. Keeping the rules for a
   moment in case other surfaces reuse them; otherwise dead.
   TODO: prune in a separate cleanup pass. */
.photo-gallery-meta {
    padding: 6px 10px;
}
.photo-caption {
    font-size: 0.8rem;
    margin-bottom: 2px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.photo-credit {
    font-size: 0.75rem;
    color: var(--color-text-light);
}
.photo-gallery-item.photo-pending {
    position: relative;
    opacity: 0.7;
}
.photo-pending-badge {
    position: absolute;
    top: 8px;
    left: 8px;
    background: rgba(0, 0, 0, 0.7);
    color: var(--color-white);
    font-size: 0.7rem;
    font-weight: 600;
    padding: 2px 8px;
    border-radius: var(--radius-card);
    z-index: 1;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
.photo-upload-section {
    margin-top: 24px;
    padding: 20px 40px 16px 16px;
    border-top: 1px solid var(--color-border);
}
.photo-upload-section h3 {
    margin-bottom: 12px;
}

.photo-dropzone {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 120px;
    padding: 20px 16px;
    border: 2px dashed var(--color-border);
    border-radius: var(--radius);
    background: var(--color-surface);
    color: var(--color-text-light);
    text-align: center;
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s, color 0.15s;
}
.photo-dropzone:hover {
    border-color: var(--color-primary);
    color: var(--color-text);
}
.photo-dropzone.is-dragover {
    border-color: var(--color-primary);
    background: var(--color-primary-tint);
    color: var(--color-text);
}
.photo-dropzone input[type="file"] {
    /* Visually hidden but still focusable so click-to-browse and
       keyboard activation work via the label. */
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    border: 0;
}
.photo-dropzone-prompt {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 0.95rem;
}
.photo-dropzone-icon {
    display: inline-flex;
    width: 28px;
    height: 28px;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--color-white);
    border: 1px solid var(--color-border);
    font-size: 1rem;
    font-weight: 600;
}
.photo-dropzone-link {
    color: var(--color-primary);
    text-decoration: underline;
}
.photo-dropzone-filename {
    font-size: 0.85rem;
    color: var(--color-text);
    font-weight: 500;
    word-break: break-all;
}
.photo-dropzone-filename.is-error {
    color: var(--color-error);
}

.area-section { margin-bottom: 24px; }
.area-section h2 {
    font-size: 1.15rem;
    font-weight: 600;
    margin-bottom: 12px;
    color: var(--color-primary-dark);
}

/* ---------------------------------------------------------------------------
   Badges
   --------------------------------------------------------------------------- */
.badge {
    display: inline-block;
    font-size: 0.75rem;
    padding: 2px 8px;
    border-radius: var(--radius);
    font-weight: 500;
    margin-right: 4px;
    text-decoration: none;
}
a.badge:hover {
    /* Subtle darken on hover so clickable badges hint at it without
       changing the brand color palette (#47 Phase 4). */
    filter: brightness(0.92);
}

/* /search empty-result CTA (#47 Phase 5). When filters return zero,
   surface a one-click "drop this chip" for each active filter so the
   user can broaden out without having to find the chip strip again. */
.search-empty-state {
    padding: 32px 20px;
    text-align: center;
}
.search-empty-suggestions {
    margin-top: 10px;
    font-size: 0.92rem;
    color: var(--color-text-light);
}
.search-empty-suggestion {
    display: inline-block;
    margin: 0 4px;
    padding: 2px 10px;
    background: var(--color-bg);
    border-radius: 999px;
    color: var(--color-primary);
    text-decoration: none;
    font-size: 0.85rem;
}
.search-empty-suggestion:hover {
    filter: brightness(0.94);
}

/* ---------------------------------------------------------------------------
   Prix-fixe / buffet / character-dining menus (#97)
   Used on /restaurants/{slug}/menu when a menu's pricing_model is
   not 'a_la_carte'. Renders the menu as a card with a pricing header
   ($N per adult / per child), then "included" categories (buffet
   stations or course choices) followed by collapsed beverage add-ons.
   --------------------------------------------------------------------------- */

.prixfixe-menu {
    background: var(--color-white);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    overflow: hidden;
    margin-bottom: 24px;
}
.prixfixe-header {
    /* Matches .page-heading-card pattern: white card with a 4px
       primary-color top accent. Reads as a section header rather than
       a marketing hero. */
    background: var(--color-white);
    border-top: 4px solid var(--color-primary);
    padding: 22px 32px 22px;
    text-align: center;
}
.prixfixe-eyebrow {
    color: var(--color-primary);
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    margin: 0 0 6px;
}
.prixfixe-title {
    color: var(--color-text);
    font-size: 1.6rem;
    margin: 0 0 16px;
    font-weight: 700;
}
.prixfixe-pricing {
    display: flex;
    justify-content: center;
    gap: 40px;
    margin-bottom: 8px;
}
.prixfixe-price {
    display: flex;
    flex-direction: column;
    align-items: center;
    color: var(--color-text);
}
.prixfixe-price-amount {
    font-size: 2.1rem;
    font-weight: 700;
    line-height: 1;
    color: var(--color-text);
}
.prixfixe-price-label {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    margin-top: 4px;
    color: var(--color-text-light);
}
.prixfixe-pricenote {
    color: var(--color-text-light);
    font-size: 0.78rem;
    margin: 8px 0 0;
}
.prixfixe-section {
    padding: 20px 24px;
    border-top: 1px solid rgba(0, 0, 0, 0.06);
}
.prixfixe-section-heading {
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--color-text);
    margin: 0 0 14px;
}
.prixfixe-section-hint {
    font-weight: 400;
    color: var(--color-text-light);
    font-size: 0.85rem;
}
.prixfixe-section-addons {
    background: var(--color-bg);
}
/* <details>/<summary> collapse for add-on sections. */
details.prixfixe-section {
    padding: 0;
}
details.prixfixe-section[open] {
    padding-bottom: 14px;
}
.prixfixe-section-summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 24px;
    cursor: pointer;
    list-style: none;
    user-select: none;
}
.prixfixe-section-summary::-webkit-details-marker {
    display: none;
}
.prixfixe-section-summary:hover {
    background: rgba(0, 0, 0, 0.03);
}
.prixfixe-section-heading-inline {
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--color-text);
}
.prixfixe-section-toggle {
    font-size: 0.85rem;
    color: var(--color-text-light);
    transition: transform 0.15s ease;
}
details[open] .prixfixe-section-toggle {
    transform: rotate(180deg);
}
details.prixfixe-section .prixfixe-items {
    padding: 0 24px;
}
.prixfixe-items {
    list-style: none;
    margin: 0;
    padding: 0;
}
.prixfixe-item {
    padding: 10px 0;
    border-bottom: 1px dashed rgba(0, 0, 0, 0.05);
}
.prixfixe-item:last-child {
    border-bottom: none;
}
.prixfixe-item-name {
    color: var(--color-text);
    font-weight: 600;
    text-decoration: none;
    font-size: 0.95rem;
}
.prixfixe-item-name:hover {
    color: var(--color-primary);
}
.prixfixe-item-desc {
    color: var(--color-text-light);
    font-size: 0.82rem;
    margin: 4px 0 0;
    line-height: 1.4;
}
.prixfixe-item-row {
    display: flex;
    align-items: baseline;
    gap: 6px;
}
.prixfixe-item-dots {
    flex: 1;
    border-bottom: 1px dotted rgba(0, 0, 0, 0.18);
    position: relative;
    top: -3px;
}
.prixfixe-item-price {
    font-variant-numeric: tabular-nums;
    color: var(--color-text);
    font-size: 0.9rem;
}
.prixfixe-item-price-missing {
    font-style: italic;
    color: var(--color-text-light);
}

/* Zero-result suggestions section (#47 Phase 5 follow-up). When the
   filters produce nothing, we surface "Popular at {scope}" alternatives
   beneath the chip-removal CTAs. Visually distinct from the horizontal
   list-style search result cards — these are image-prominent grid tiles
   (modeled after .blog-featured-card) so the user reads them as a
   different kind of content: invitations, not matches. */
.search-suggestions {
    background: var(--color-bg);
    border-radius: var(--radius-lg);
    padding: 20px 18px 18px;
    margin-top: 18px;
    border: 1px dashed rgba(0, 0, 0, 0.08);
}
.search-suggestions-eyebrow {
    color: var(--color-text-light);
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    margin: 0 0 4px;
}
.search-suggestions-heading {
    font-size: 1.05rem;
    color: var(--color-text);
    margin: 0 0 14px;
    font-weight: 600;
}
.search-suggestion-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 12px;
}
@media (min-width: 769px) {
    .search-suggestion-grid {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}
.search-suggestion-card {
    display: flex;
    flex-direction: column;
    background: var(--color-white);
    border-radius: var(--radius-lg);
    overflow: hidden;
    text-decoration: none;
    color: inherit;
    box-shadow: var(--shadow);
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.search-suggestion-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
}
.search-suggestion-card-image {
    position: relative;
    aspect-ratio: 4 / 3;
    background: var(--color-bg);
    overflow: hidden;
}
.search-suggestion-card-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
/* hsl-letter placeholder. Background hue set inline (crc32 hash
   of the name); same treatment used across the site. */
.search-suggestion-card-image-empty {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    color: rgba(255, 255, 255, 0.92);
    font-size: 2.4rem;
    font-weight: 700;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
}
/* Badge wrapper positions the rating chip at the image's top-
   right. For menu items the chip is renderThumbsBadge()'s tonal %
   pill; for venues it's the numeric+stars chip below. (#153
   followup) */
.search-suggestion-card-badge {
    position: absolute;
    top: 8px;
    right: 8px;
    display: inline-flex;
}
.search-suggestion-card-stars {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px 8px;
    background: rgba(255, 255, 255, 0.95);
    border-radius: 999px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12);
    font-size: 0.78rem;
    font-weight: 700;
    color: var(--color-header);
    font-variant-numeric: tabular-nums;
}
.search-suggestion-card-stars strong {
    line-height: 1;
}
.search-suggestion-card-body {
    padding: 10px 12px 12px;
}
.search-suggestion-card-title {
    font-size: 0.95rem;
    font-weight: 600;
    line-height: 1.25;
    margin: 0 0 4px;
    /* Clamp to 2 lines so all cards in the row stay the same height. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.search-suggestion-card-subtitle {
    font-size: 0.78rem;
    color: var(--color-text-light);
    margin: 0;
    /* Same clamping — keeps grid rows aligned. */
    display: -webkit-box;
    -webkit-line-clamp: 1;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Park-scoped search section (#47 Phase 3). Sits between the heading
   card and the area-grouped restaurant list. Reuses .home-searchbar
   for the bar itself; .park-searchbar-section provides spacing and
   the small context line above the bar. */
.park-searchbar-section {
    margin: 12px 0 20px;
}
.park-searchbar-context {
    text-align: center;
    color: var(--color-text-light);
    font-size: 0.85rem;
    margin: 0 0 10px;
}
.park-searchbar-context strong {
    color: var(--color-text);
}
.badge-service { background: #E3F2FD; color: #1565C0; }
.badge-cuisine { background: #F3E5F5; color: #7B1FA2; }
.badge-price { background: #E8F5E9; color: #2E7D32; }
.badge-style { background: #FFF3E0; color: #E65100; }
.badge-dietary { background: #FFF8E1; color: #8a6d1d; }
/* Venue-type pill (#326). Soft blue (Brandon 2026-07-15) — the
   previous slate read as "disabled." Blue keeps the informational
   tone without the alarm-color of coral or the muted feeling of
   grey, and matches the same palette .badge-service uses on the
   restaurant detail page for cross-page consistency. */
.badge-venue-type { background: #E3F2FD; color: #1565C0; }
/* Disney Dining Plan pill (#333). Amber-tinted to read as "ticket"
   next to the DDP glyph (🎟). The -est variant is used for menu items
   whose eligibility is inferred via the coarse rule rather than
   confirmed by scrape or admin — softer background, dashed border so
   users can tell the difference at a glance. */
/* DDP coin — self-contained visual (Brandon 2026-07-15). The
   earlier .badge-ddp pill chrome around the coin was redundant
   with the coin's own gold rim + coral ring; retired here.
   Menu-item detail page still uses .menu-item-ddp-pill for the
   text-adjacent case ("Redeems for 1 Snack Credit"). */
.ddp-coin {
    width: 20px;
    height: 20px;
    display: inline-block;
    vertical-align: middle;
    flex-shrink: 0;
}
/* Muted variant for menu-item snack tiles where eligibility is
   coarse-rule inferred rather than confirmed by scrape or admin.
   Preserves the "less certain" signal without a border/pill. */
.ddp-coin-est {
    opacity: 0.55;
}
/* Standalone clickable coin (restaurant detail page). Plain
   anchor — no chrome — that scopes /search to peers on the same
   credit tier. Small hover lift so it reads as interactive. */
.ddp-coin-link {
    display: inline-flex;
    align-items: center;
    line-height: 1;
    transition: transform 0.15s ease;
}
.ddp-coin-link:hover {
    transform: scale(1.08);
}
.menu-item-ddp-pill .ddp-coin {
    margin-right: 4px;
}

/* Score badges */
.score-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--color-white);
}
.score-green { background: var(--color-score-green); }
.score-yellow-green { background: var(--color-score-yellow-green); }
.score-yellow { background: var(--color-score-yellow); color: var(--color-text); }
.score-orange { background: var(--color-score-orange); }
.score-red { background: var(--color-score-red); }

/* Dietary tag pills */
.tag-pill {
    display: inline-block;
    font-size: 0.75rem;
    font-weight: 500;
    padding: 4px 10px;
    border-radius: 999px;
    margin: 2px 4px 2px 0;
}
.tag-green { background: #E8F5E9; color: #2E7D32; }
.tag-coral { background: #FFEBEE; color: #C62828; }
.tag-blue { background: #E3F2FD; color: #1565C0; }

/* ---------------------------------------------------------------------------
   Menu Items
   --------------------------------------------------------------------------- */
.menu-section { margin-bottom: 24px; }
.menu-section h2 {
    font-size: 1.15rem;
    font-weight: 600;
    margin-bottom: 12px;
    border-bottom: 2px solid var(--color-primary);
    padding-bottom: 4px;
}
.menu-category-title {
    font-size: 1.1rem;
    font-weight: 600;
    margin-top: 24px;
    margin-bottom: 10px;
    padding-bottom: 6px;
    border-bottom: 2px solid var(--color-primary);
    color: var(--color-text);
    display: inline-block;
}
.menu-items { display: flex; flex-direction: column; gap: 8px; }
.menu-item {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    background: var(--color-white);
    border-radius: var(--radius-lg);
    padding: 12px 16px;
    box-shadow: var(--shadow);
}
.menu-item-info { flex: 1; min-width: 0; }
.menu-item-info h3 { font-size: 1rem; margin-bottom: 4px; }
.item-description {
    font-size: 0.72rem;
    color: var(--color-text-light);
    font-weight: 400;
    margin: 0;
    line-height: 1.35;
    /* No clamp — boxes grow to fit. Mirrors My Disney Experience's
       Mobile Order tiles where Disney curates descriptions short
       enough that the tile heights mostly stay uniform. */
}
.item-description-full {
    /* Detail page keeps multi-line; tile uses .item-description (truncated). */
    font-size: 0.875rem;
    color: var(--color-text-light);
}
.item-category { font-size: 0.75rem; color: var(--color-text-light); font-style: italic; }
.item-location { font-size: 0.8rem; color: var(--color-text-light); }
.item-location a { font-weight: 500; }
.menu-item-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-shrink: 0;
    margin-left: 12px;
}
.item-price {
    font-weight: 600;
    font-size: 1rem;
    color: var(--color-primary-dark);
    white-space: nowrap;
}

/* ---------------------------------------------------------------------------
   List-add Button (+ picker)
   --------------------------------------------------------------------------- */
.btn-list-add {
    background: var(--color-white);
    border: 1.5px solid var(--color-border);
    color: var(--color-text-light);
    width: 32px;
    height: 32px;
    border-radius: 50%;
    cursor: pointer;
    font-size: 1.25rem;
    font-weight: 300;
    line-height: 1;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: background 0.15s, border-color 0.15s, color 0.15s, transform 0.15s;
}
.btn-list-add:hover {
    border-color: var(--color-primary);
    color: var(--color-primary);
    transform: scale(1.05);
}
.btn-list-add.in-list {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: var(--color-white);
}
.btn-list-add.in-list:hover {
    background: var(--color-primary);
    color: var(--color-white);
}

/* ---------------------------------------------------------------------------
   List-picker Popover
   --------------------------------------------------------------------------- */
.list-picker-popover {
    position: absolute;
    z-index: 1000;
    width: 240px;
    background: var(--color-white);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: var(--shadow-hover);
    font-size: 0.9rem;
}
.list-picker-header {
    padding: 10px 14px;
    border-bottom: 1px solid var(--color-border);
    font-weight: 600;
    color: var(--color-text);
}
.list-picker-body {
    padding: 6px 0;
    max-height: 320px;
    overflow-y: auto;
}
.list-picker-row {
    display: flex;
    align-items: center;
    padding: 8px 14px;
    cursor: pointer;
    gap: 10px;
}
.list-picker-row:hover {
    background: var(--color-surface);
}
.list-picker-row input[type="checkbox"] {
    margin: 0;
    cursor: pointer;
}
.list-picker-name {
    flex: 1;
    color: var(--color-text);
}
.list-picker-count {
    color: var(--color-text-light);
    font-size: 0.8rem;
}
.list-picker-teaser {
    margin-top: 6px;
    padding: 10px 14px;
    border-top: 1px dashed var(--color-border);
    color: var(--color-text-light);
    font-size: 0.8rem;
    font-style: italic;
}
.list-picker-error {
    margin: 6px 14px;
    padding: 8px 10px;
    background: #FFEBEE;
    color: var(--color-error);
    border: 1px solid #EF9A9A;
    border-radius: var(--radius);
    font-size: 0.85rem;
}

/* ---------------------------------------------------------------------------
   Search Page
   --------------------------------------------------------------------------- */
.search-form { margin-bottom: 24px; }
.search-bar-page { display: flex; gap: 8px; margin-bottom: 12px; }
.search-filters { display: flex; gap: 8px; flex-wrap: wrap; }
.filter-select {
    padding: 8px 32px 8px 12px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    font-size: 0.875rem;
    font-family: var(--font-family);
    background: var(--color-white);
}

/* Unified select chevron — replace the native dropdown arrow with a
   consistent SVG so the indicator sits at a uniform offset on every
   <select> across the site. Without this, browsers position the
   native arrow flush to the right edge with their own padding, which
   reads inconsistent next to our custom buttons. */
.filter-select,
select.form-input {
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8' fill='none' stroke='%230D2B52' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='1 1 6 6 11 1'/></svg>");
    background-repeat: no-repeat;
    background-position: right 12px center;
    background-size: 10px;
}
select.form-input {
    padding-right: 32px;
    background-color: var(--color-white);
}
.results-count { color: var(--color-text-light); margin-bottom: 12px; }
.search-page-btn { padding: 10px 24px; }

/* Compact heading for the search-results state (#50 review tweak). The
   heavy page-heading-card chrome dwarfs the actual content when the
   user is in working/query mode rather than landing on the directory. */
.search-results-heading {
    font-size: 1.4rem;
    font-weight: 600;
    margin: 4px 0 16px;
    color: var(--color-text);
}

/* "Advanced" toggle row (#132 D) — single button that collapses ALL
   filter + sort controls behind one panel. Default state shows only
   the search bar; the toggle reveals service type, park, cuisine,
   dietary need, and sort in a labeled grid. Toggle is right-aligned
   so it stays out of the way until needed and auto-flips to its
   active state when any filter/sort is set on page load. */
.search-filters-bar {
    margin-top: 10px;
    justify-content: flex-end;
}
/* Hide the Advanced toggle on desktop — pills are inline by default
   at >=769px. Mobile keeps the toggle so guests can collapse the
   pill row when they're focused on the results. (#132 D5) */
@media (min-width: 769px) {
    .search-filters-bar {
        display: none;
    }
}
.more-filters-toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 8px 14px;
    background: var(--color-bg-light);
    color: var(--color-text);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.more-filters-toggle:hover {
    background: var(--color-bg);
}
.more-filters-toggle.is-active {
    border-color: var(--color-primary);
    color: var(--color-primary);
    background: var(--color-white);
}
.more-filters-caret { font-size: 0.75em; }
.more-filters-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    height: 20px;
    padding: 0 6px;
    background: var(--color-primary);
    color: var(--color-white);
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 700;
    letter-spacing: 0;
}

/* Search toolbar — sticky search bar + filter section (#132 D6,
   per Brandon 2026-06-18). Inspired by Amazon's mobile filter
   bar: search row pinned to the top, then a separate filter
   section divided by a thin border, with a Filters button on
   the left and horizontally-scrollable pill chips to its right.
   Stays visible as the user scrolls results. */
/* Search toolbar — card-style chrome. Mobile-first: tighter padding
   so the input and chip row don't waste horizontal space; desktop
   bumps it back up for editorial comfort. (#132 + #136) */
.search-toolbar {
    position: sticky;
    top: 0;
    z-index: 40;
    background: var(--color-white);
    margin: 0 0 8px;
    padding: 8px 10px;
    border: var(--card-border);
    border-radius: var(--radius-card);
}
@media (min-width: 769px) {
    .search-toolbar {
        margin: 0 0 12px;
        padding: 10px 14px;
    }
}
.search-toolbar-bar {
    display: flex;
    gap: 8px;
    align-items: stretch;
}

/* Sort + Filters share an actions container to the right of the
   search input. On mobile they stack vertically as small round
   circles so the search pill reclaims width; on desktop they sit
   side-by-side as full 44px circles. (#147 followup) */
.search-toolbar-actions {
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
    align-items: center;
    justify-content: center;
}
.search-toolbar-actions > .filter-sheet-trigger,
.search-toolbar-actions > .search-toolbar-sort,
.search-toolbar-actions > .search-toolbar-sort > summary.filter-sheet-trigger {
    width: 24px;
    height: 24px;
    flex: 0 0 auto;
}
.search-toolbar-actions .filter-sheet-trigger-icon {
    width: 12px;
    height: 12px;
}
@media (min-width: 769px) {
    /* Desktop: round 44px circles side-by-side. */
    .search-toolbar-actions {
        flex-direction: row;
        gap: 8px;
    }
    .search-toolbar-actions > .filter-sheet-trigger,
    .search-toolbar-actions > .search-toolbar-sort {
        width: 44px;
        height: 44px;
    }
    .search-toolbar-actions > .search-toolbar-sort > summary.filter-sheet-trigger {
        width: 100%;
        height: 100%;
    }
    .search-toolbar-actions .filter-sheet-trigger-icon {
        width: 20px;
        height: 20px;
    }
}
/* Pill-shape input-group — matches the rounded affordance the
   homepage search bar has always had so the search chrome stays
   consistent site-wide (Brandon 2026-06-18). The submit lives
   inside the pill as a smaller circle inset from the right edge,
   rather than clipped to the pill's right curve. */
.search-toolbar-input-group {
    display: flex;
    align-items: center;
    flex: 1;
    background: var(--color-white);
    border: 2px solid var(--color-border);
    border-radius: 999px;
    padding: 4px 4px 4px 4px;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.search-toolbar-input-group:focus-within {
    border-color: var(--color-primary);
    box-shadow: 0 0 0 3px rgba(255, 90, 71, 0.12);
}
.search-toolbar-input {
    flex: 1;
    min-width: 0;
    /* Aggressively kill native input chrome — some browsers
       inject inset borders, shadows, or autofill backgrounds
       even when border:none is set. */
    appearance: none;
    -webkit-appearance: none;
    border: 0;
    background: transparent;
    box-shadow: none;
    padding: 8px 8px 8px 16px;
    /* 16px (1rem) is the iOS Safari zoom threshold — anything
       smaller and focusing the input triggers a magnification
       zoom on iPhones. Holding at exactly 16px keeps the
       compact look without firing the zoom. */
    font-size: 1rem;
    font-family: var(--font-family);
    color: var(--color-text);
    outline: none;
}
.search-toolbar-input::placeholder { color: var(--color-text-light); }
.search-toolbar-submit {
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    background: var(--color-primary);
    color: var(--color-white);
    border: 0;
    border-radius: 50%;
    cursor: pointer;
    transition: background 0.15s ease;
}
.search-toolbar-submit:hover {
    background: var(--color-primary-dark);
}
.search-toolbar-filters {
    position: relative;
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid var(--color-border);
}
/* Edge-fade gradients sit on top of the pill row at left + right
   edges. pointer-events: none so they don't intercept clicks.
   Hidden on desktop where the row wraps and no scroll hint is
   needed. Pseudo-element strategy (instead of mask-image on
   .filter-pills) avoids creating a new containing block — fixed-
   position popovers stay positioned relative to the viewport. */
.search-toolbar-filters::before,
.search-toolbar-filters::after {
    content: '';
    position: absolute;
    top: 10px;
    bottom: 0;
    width: 20px;
    pointer-events: none;
    z-index: 1;
}
.search-toolbar-filters::before {
    left: 0;
    background: linear-gradient(to right, var(--color-white), transparent);
}
.search-toolbar-filters::after {
    right: 0;
    background: linear-gradient(to left, var(--color-white), transparent);
}
@media (min-width: 769px) {
    .search-toolbar-filters::before,
    .search-toolbar-filters::after {
        display: none;
    }
}

/* Filters button (opens the full-screen sheet). Sits on the left
   of the pill row and stays anchored while the pill row scrolls
   on mobile. */
/* Icon-only square button (#136 polish) — sliders glyph, no
   "Filters" label. Matches the search input's height (stretched
   via flex parent) and the search submit button's 44px width so
   the toolbar reads as one even row. Stays two-tone white/grey
   in all states (no coral fill) — the count badge alone signals
   active filters, leaving the orange identity to the search
   submit button. */
.filter-sheet-trigger {
    position: relative;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    background: var(--color-bg-light);
    border: 1px solid var(--color-border);
    border-radius: 50%;
    color: var(--color-text);
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease;
}

/* Sort button (#147 item 3) — sits beside Filters, same icon-only
   chrome. Override the pill-shaped .filter-pill > summary styles
   that would otherwise win on specificity. */
.search-toolbar-sort {
    position: relative;
    flex-shrink: 0;
}
.search-toolbar-sort > summary.filter-sheet-trigger {
    padding: 0;
    border-radius: 50%;
    font-size: inherit;
    font-weight: inherit;
    white-space: normal;
    /* Explicit 44px square so the summary renders as a circle when
       the parent .search-toolbar-sort isn't constrained by an
       outer wrapper. (/search's wrapper provides sizing via
       .search-toolbar-actions; standalone usage like the menu
       page Sort button needs this fallback.) */
    width: 44px;
    height: 44px;
}
.search-toolbar-sort[open] > summary.filter-sheet-trigger {
    background: var(--color-bg);
    border-color: var(--color-text-light);
}

.filter-sheet-trigger:hover,
.filter-sheet-trigger:focus-visible {
    background: var(--color-bg);
    border-color: var(--color-text-light);
    outline: none;
}
.filter-sheet-trigger-icon {
    display: block;
}
/* Count badge overlays the top-right corner. Coral fill carries
   the only "active filters" signal now that the button stays
   neutral. */
.filter-sheet-trigger-count {
    position: absolute;
    top: -6px;
    right: -6px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    background: var(--color-primary);
    color: var(--color-white);
    border: 2px solid var(--color-white);
    border-radius: 999px;
    font-size: 0.65rem;
    font-weight: 800;
    line-height: 1;
}

/* Pill row — horizontal scroll on narrow viewports so chips never
   wrap onto a second line. The Filters button stays fixed on the
   left of the row; pills swipe horizontally inside their own
   container. */
/* Pill row horizontally scrolls on mobile, wraps on desktop.
   Popovers (.filter-pill-panel) escape this overflow container via
   `position: fixed` + JS-driven coords on open. The edge-fade hint
   lives on .search-toolbar-filters as a pseudo-element gradient
   (below) — earlier this used `mask-image` on .filter-pills, but
   `mask-image` creates a new containing block for fixed-position
   descendants in most browsers, which broke the popover coords
   (popovers jumped offscreen). Pseudo-element gradients on the
   wrapper have no such side effect. */
.filter-pills {
    display: flex;
    flex-wrap: nowrap;
    gap: 6px;
    overflow-x: auto;
    overflow-y: visible;
    flex: 1;
    scrollbar-width: none;
}
.filter-pills::-webkit-scrollbar { display: none; }
/* Row stays single-line at every breakpoint (Brandon 2026-07-12):
   with the DDP credit-type quick chips added, desktop wrap-to-second-
   row created a visual layer that clashed with the tight header row.
   Horizontal scroll keeps the pill row as a single scannable band. */

/* Filter pill — matches the design system used by the Filters
   button, breadcrumb chips, and page-heading-card. Chip is a
   pill-shaped button (same bg-light background as .filter-sheet-
   trigger), popover is a card-chrome overlay floating below. */
.filter-pill {
    position: relative;
}

/* Single-click toggle chips (#136). No popover — clicking flips
   the URL flag on/off via auto-submit on the hidden checkbox.
   Same visual family as .filter-pill > summary so the row reads
   uniformly. */
.filter-toggle {
    position: relative;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    background: var(--color-bg-light);
    border: 1px solid var(--color-border);
    border-radius: 999px;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--color-text);
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
    white-space: nowrap;
    user-select: none;
}
.filter-toggle:hover {
    border-color: var(--color-primary);
}
.filter-toggle input {
    position: absolute;
    inset: 0;
    opacity: 0;
    cursor: pointer;
    margin: 0;
}
.filter-toggle.is-active {
    background: var(--color-primary);
    color: var(--color-white);
    border-color: var(--color-primary);
}
.filter-pill > summary {
    list-style: none;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    background: var(--color-bg-light);
    border: 1px solid var(--color-border);
    border-radius: 999px;
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--color-text);
    cursor: pointer;
    transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
    white-space: nowrap;
}
.filter-pill > summary::-webkit-details-marker {
    display: none;
}
.filter-pill > summary:hover {
    border-color: var(--color-primary);
}
.filter-pill[open] > summary {
    border-color: var(--color-primary);
}
.filter-pill.is-active > summary {
    background: var(--color-primary);
    color: var(--color-white);
    border-color: var(--color-primary);
}
.filter-pill-name {
    font-weight: 700;
}
.filter-pill-state {
    color: var(--color-text-light);
    font-weight: 500;
    max-width: 12em;
    overflow: hidden;
    text-overflow: ellipsis;
}
.filter-pill.is-active .filter-pill-state {
    color: rgba(255, 255, 255, 0.9);
    font-weight: 600;
}
.filter-pill-caret {
    font-size: 0.7em;
    color: var(--color-text-light);
}
.filter-pill.is-active .filter-pill-caret {
    color: var(--color-white);
}

/* Popover overlay — `position: fixed` so it escapes the pill row's
   `overflow-x: auto` clip box and overlays the content below the
   row instead of being trapped inside a vertical scroll within the
   narrow strip (#147 item 1). JS in templates/search.html sets the
   top/left coords from the pill's getBoundingClientRect() at open
   time so it still visually anchors to the pill. */
.filter-pill-panel {
    position: fixed;
    z-index: 50;
    min-width: 240px;
    max-width: 320px;
    background: var(--color-white);
    border: var(--card-border);
    border-radius: var(--radius-card);
    box-shadow: 0 10px 28px rgba(13, 43, 82, 0.16);
    padding: 8px;
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.filter-pill-panel-scroll {
    max-height: 320px;
    overflow-y: auto;
}

/* Each option = one row. Subtle hover; active gets the same coral
   tint used elsewhere for "this is your current selection". */
.pill-option {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 10px;
    border-radius: var(--radius);
    font-size: 0.88rem;
    color: var(--color-text);
    cursor: pointer;
    transition: background 0.1s ease;
}
.pill-option:hover {
    background: var(--color-bg-light);
}
.pill-option input {
    accent-color: var(--color-primary);
    cursor: pointer;
}
.pill-option.is-active {
    background: rgba(255, 90, 71, 0.08);
    font-weight: 600;
    color: var(--color-header);
}
.pill-option-icon {
    font-size: 1rem;
    line-height: 1;
}
.pill-option-label {
    flex: 1;
    min-width: 0;
}
.pill-option-count {
    color: var(--color-text-light);
    font-size: 0.78rem;
    font-weight: 500;
}
.pill-option.is-active .pill-option-count {
    color: var(--color-primary);
}

/* Apply / Clear action row — same pattern as the filter sheet
   foot. Outline button for Clear, primary fill for Apply. */
.filter-pill-actions {
    display: flex;
    gap: 8px;
    padding: 8px 4px 2px;
    margin-top: 6px;
    border-top: 1px solid var(--color-border);
}
.pill-action {
    flex: 1;
    padding: 6px 12px;
    font-size: 0.82rem;
    font-weight: 600;
    border-radius: var(--radius);
    cursor: pointer;
    border: 1px solid transparent;
    background: transparent;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
    font-family: var(--font-family);
}
.pill-action-clear {
    color: var(--color-text-light);
    border-color: var(--color-border);
    background: var(--color-white);
}
.pill-action-clear:hover {
    border-color: var(--color-text-light);
    color: var(--color-header);
}
.pill-action-apply {
    background: var(--color-primary);
    color: var(--color-white);
    border-color: var(--color-primary);
}
.pill-action-apply:hover {
    background: var(--color-primary-dark);
    border-color: var(--color-primary-dark);
}

/* Full-screen Filters sheet (#132 D6). Position-fixed overlay with
   a backdrop. Slides up from the bottom on mobile, slides in from
   the right on desktop. Inputs inside live in the main <form> so
   Apply submits the whole search state at once. */
.filter-sheet[hidden] { display: none; }
.filter-sheet {
    position: fixed;
    inset: 0;
    z-index: 100;
    display: flex;
}
.filter-sheet-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(13, 43, 82, 0.45);
}
.filter-sheet-body {
    position: relative;
    margin-left: auto;
    width: min(440px, 100%);
    height: 100%;
    background: var(--color-white);
    display: flex;
    flex-direction: column;
    box-shadow: -8px 0 24px rgba(0, 0, 0, 0.18);
    animation: filter-sheet-in 0.18s ease;
}
@keyframes filter-sheet-in {
    from { transform: translateX(20%); opacity: 0.4; }
    to   { transform: translateX(0); opacity: 1; }
}
@media (max-width: 600px) {
    .filter-sheet-body {
        width: 100%;
        margin: 10vh 0 0;
        max-height: 90vh;
        border-radius: var(--radius) var(--radius) 0 0;
        animation: filter-sheet-up 0.2s ease;
    }
    @keyframes filter-sheet-up {
        from { transform: translateY(20%); opacity: 0.4; }
        to   { transform: translateY(0); opacity: 1; }
    }
}
body.is-filter-sheet-open { overflow: hidden; }

.filter-sheet-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 18px;
    border-bottom: 1px solid var(--color-border);
}
.filter-sheet-head h2 {
    margin: 0;
    font-size: 1.1rem;
    color: var(--color-header);
}
.filter-sheet-close {
    background: transparent;
    border: 0;
    font-size: 1.6rem;
    line-height: 1;
    color: var(--color-text-light);
    cursor: pointer;
    padding: 4px 8px;
}
.filter-sheet-close:hover { color: var(--color-header); }
.filter-sheet-content {
    flex: 1;
    overflow-y: auto;
    padding: 14px 18px;
    display: flex;
    flex-direction: column;
    gap: 22px;
}
.filter-sheet-section-title {
    margin: 0 0 8px;
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    font-weight: 700;
    color: var(--color-text-light);
}
.filter-sheet-empty {
    margin: 0;
    color: var(--color-text-light);
    font-size: 0.88rem;
    font-style: italic;
}
/* Flex-wrap chip layout so options flow horizontally sized to
   content (#132 D7). Short labels like "Quick Service" or "$$$"
   pack tightly on one row; longer ones wrap naturally. Saves
   vertical space compared with the prior 2-3 column grid where
   every option occupied a full cell. */
.filter-sheet-option-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}
.sheet-option {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 8px 10px;
    background: var(--color-bg-light);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    font-size: 0.85rem;
    color: var(--color-text);
    cursor: pointer;
    transition: background 0.1s ease, border-color 0.1s ease;
}
.sheet-option:hover {
    border-color: var(--color-primary);
}
.sheet-option.is-active {
    background: var(--color-primary);
    color: var(--color-white);
    border-color: var(--color-primary);
}
.sheet-option input { accent-color: var(--color-primary); }
.sheet-option-label { flex: 1; }
.sheet-option-count {
    font-size: 0.78rem;
    opacity: 0.85;
}
.filter-sheet-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 18px;
    border-top: 1px solid var(--color-border);
    background: var(--color-white);
}
.filter-sheet-clear {
    font-size: 0.82rem;
    color: var(--color-text-light);
    text-decoration: underline;
}
.filter-sheet-clear:hover { color: var(--color-primary); }
.filter-sheet-apply { padding: 8px 20px; }

/* Active-filter chip strip (#50). Renders the currently-selected
   filters as removable pills so users can see what's narrowing the
   list and clear individual filters without dropping back into the
   selects. */
.active-filter-chips {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: 0 0 16px;
    padding: 8px 12px;
    background: var(--color-bg-light);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-card);
}
.active-filter-label {
    color: var(--color-text-light);
    font-size: 0.85rem;
    font-weight: 500;
}
.active-filter-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px 10px;
    background: var(--color-primary-tint);
    color: var(--color-primary-dark);
    border-radius: 999px;
    font-size: 0.85rem;
    text-decoration: none;
    transition: background 0.15s ease;
}
.active-filter-chip:hover {
    background: rgba(255, 90, 71, 0.22);
}
.active-filter-chip-x {
    font-size: 1.1em;
    line-height: 1;
    opacity: 0.7;
}
.active-filter-clear {
    margin-left: auto;
    color: var(--color-text-light);
    font-size: 0.85rem;
    text-decoration: underline;
}

/* Park grouping in the browse/filtered modes — each park gets its own
   subheading + tile list so 400+ restaurants don't render as one
   undifferentiated wall. */
.park-group { margin-bottom: 28px; }
.park-group-heading {
    font-size: 1rem;
    font-weight: 600;
    color: var(--color-header);
    margin: 0 0 12px;
    padding-bottom: 6px;
    border-bottom: 1px dashed var(--color-border);
}
.park-group-count {
    color: var(--color-text-light);
    font-weight: 400;
    font-size: 0.9em;
}

/* Pagination on the directory view. Simple prev/next + "Page X of Y"
   indicator. */
.search-pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    margin: 24px 0 8px;
}
.search-pagination-info {
    color: var(--color-text-light);
    font-size: 0.9rem;
}
.search-pagination .btn.disabled {
    opacity: 0.45;
    pointer-events: none;
    cursor: default;
}

/* Search sections */
.search-section { margin-bottom: 32px; }
.search-section-title {
    font-size: 1.15rem;
    font-weight: 600;
    margin-bottom: 16px;
    padding-bottom: 8px;
    border-bottom: 2px solid var(--color-primary);
    display: inline-block;
}
.search-section-count {
    font-weight: 400;
    color: var(--color-text-light);
    font-size: 0.9rem;
}

/* Venue cards grid */
.venue-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
    gap: 16px;
}
.venue-card {
    background: var(--color-white);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    overflow: hidden;
    display: flex;
    flex-direction: column;
    color: var(--color-text);
    transition: box-shadow 0.2s, transform 0.2s;
}
.venue-card:hover {
    box-shadow: var(--shadow-hover);
    transform: translateY(-2px);
    text-decoration: none;
    color: var(--color-text);
}
.venue-card-image {
    position: relative;
    width: 100%;
    aspect-ratio: 16/10;
    background: var(--color-bg-light);
    overflow: hidden;
}
.venue-card-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.venue-card-placeholder {
    width: 100%;
    height: 100%;
    background: #D3D3D3;
}
.venue-score {
    position: absolute;
    top: 8px;
    right: 8px;
    box-shadow: 0 2px 6px rgba(0,0,0,0.2);
}
.venue-card-body {
    padding: 12px;
}
.venue-card-body h3 {
    font-size: 0.95rem;
    font-weight: 600;
    margin-bottom: 4px;
}
.venue-card-location {
    font-size: 0.8rem;
    color: var(--color-text-light);
    margin-bottom: 8px;
}
.venue-card-badges {
    display: flex;
    gap: 4px;
    flex-wrap: wrap;
}
.venue-hidden { display: none; }

/* Search items list */
.search-items-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
}
.search-item-row {
    display: flex;
    align-items: center;
    gap: 12px;
    background: var(--color-white);
    border-radius: var(--radius-lg);
    padding: 12px 16px;
    box-shadow: var(--shadow);
}
.search-item-thumb {
    width: 56px;
    height: 56px;
    border-radius: var(--radius);
    overflow: hidden;
    flex-shrink: 0;
}
.search-item-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.search-item-info {
    flex: 1;
    min-width: 0;
}
.search-item-info h3 {
    font-size: 0.95rem;
    margin-bottom: 2px;
}
.search-item-meta {
    font-size: 0.8rem;
    color: var(--color-text-light);
    margin-bottom: 2px;
}
.search-item-meta a { font-weight: 500; }
.search-item-sep { margin: 0 4px; }
.search-item-price {
    flex-shrink: 0;
    margin-left: 8px;
}
.item-hidden { display: none; }

/* Show More button */
.btn-show-more {
    display: block;
    margin: 16px auto 0;
    padding: 10px 32px;
}

/* ---------------------------------------------------------------------------
   Breadcrumbs
   --------------------------------------------------------------------------- */
/* Breadcrumbs scroll horizontally when they exceed the viewport
   width (Brandon 2026-06-19) — wrapping to a second row was
   crowding the heading card. Hidden scrollbar; touch + trackpad
   panning is the discoverable interaction. */
.breadcrumbs {
    font-size: 0.85rem;
    color: var(--color-text-light);
    margin-bottom: 6px;
    white-space: nowrap;
    overflow-x: auto;
    overflow-y: visible;
    scrollbar-width: none;
}
.breadcrumbs::-webkit-scrollbar { display: none; }
@media (min-width: 769px) {
    .breadcrumbs { margin-bottom: 12px; }
}
.breadcrumbs a { color: var(--color-text-light); }
.breadcrumbs a:hover { color: var(--color-primary); }

.breadcrumbs-with-chips {
    display: flex;
    flex-wrap: nowrap;
    align-items: center;
    gap: 6px 8px;
    margin-bottom: 6px;
    overflow-x: auto;
    overflow-y: visible;
    scrollbar-width: none;
}
.breadcrumbs-with-chips::-webkit-scrollbar { display: none; }
@media (min-width: 769px) {
    .breadcrumbs-with-chips { margin-bottom: 10px; }
}
.breadcrumb-trail {
    color: var(--color-text-light);
    flex-shrink: 0;
}
.breadcrumb-chip-strip {
    display: inline-flex;
    flex-wrap: nowrap;
    align-items: center;
    gap: 4px;
    flex-shrink: 0;
}
.breadcrumb-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 2px 4px 2px 10px;
    background: rgba(255, 90, 71, 0.10);
    color: var(--color-header);
    border-radius: 999px;
    font-size: 0.78rem;
    font-weight: 600;
    line-height: 1.4;
    text-decoration: none;
    transition: background 0.15s ease;
}
.breadcrumb-chip:hover {
    background: rgba(255, 90, 71, 0.18);
    color: var(--color-header);
    text-decoration: none;
}
.breadcrumb-chip-label {
    max-width: 14em;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.breadcrumb-chip-x {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    background: var(--color-white);
    color: var(--color-primary);
    border-radius: 999px;
    font-size: 0.9rem;
    font-weight: 700;
    line-height: 1;
}
.breadcrumb-clear-all {
    margin-left: 4px;
    font-size: 0.78rem;
    color: var(--color-text-light);
    text-decoration: underline;
}
.breadcrumb-clear-all:hover {
    color: var(--color-primary);
}

/* Restaurant detail meta */
.restaurant-meta {
    display: flex;
    gap: 8px;
    align-items: center;
    flex-wrap: wrap;
    margin-bottom: 12px;
}
.meta-location { color: var(--color-text-light); font-size: 0.9rem; }
.restaurant-description { color: var(--color-text-light); margin-bottom: 24px; }

/* ---------------------------------------------------------------------------
   Info Table (restaurant detail)
   --------------------------------------------------------------------------- */
.info-table {
    width: 100%;
    margin-bottom: 24px;
}
.info-table tr {
    border-bottom: 1px solid var(--color-border);
}
.info-table td {
    padding: 10px 0;
    font-size: 0.9rem;
    vertical-align: top;
}
.info-table td:first-child {
    font-weight: 600;
    width: 120px;
    color: var(--color-text);
}
.info-table td:last-child {
    color: var(--color-text-light);
}

/* ---------------------------------------------------------------------------
   Tabs
   --------------------------------------------------------------------------- */
.tabs {
    display: flex;
    border-bottom: 2px solid var(--color-border);
    margin-bottom: 20px;
}
.tab {
    padding: 10px 20px;
    font-weight: 500;
    font-size: 0.9rem;
    color: var(--color-text-light);
    border: none;
    background: none;
    cursor: pointer;
    border-bottom: 2px solid transparent;
    margin-bottom: -2px;
    transition: color 0.15s, border-color 0.15s;
}
.tab:hover { color: var(--color-primary); }
.tab.active {
    color: var(--color-primary);
    border-bottom-color: var(--color-primary);
}

/* ---------------------------------------------------------------------------
   Rating Bars
   --------------------------------------------------------------------------- */
.rating-bar-row {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 8px;
}
.rating-label {
    font-size: 0.85rem;
    color: var(--color-text-light);
    min-width: 140px;
}
.rating-bar {
    flex: 1;
    height: 8px;
    background: var(--color-border);
    border-radius: var(--radius);
    overflow: hidden;
}
.rating-bar-fill {
    height: 100%;
    border-radius: var(--radius);
    background: var(--color-score-green);
}
.rating-value {
    font-size: 0.85rem;
    font-weight: 600;
    min-width: 30px;
    text-align: right;
}

/* ---------------------------------------------------------------------------
   Forms
   --------------------------------------------------------------------------- */
.form-group { margin-bottom: 16px; }
.form-group label {
    display: block;
    font-weight: 600;
    margin-bottom: 4px;
    font-size: 0.9rem;
}
.form-input {
    width: 100%;
    padding: 12px 14px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    font-size: 1rem;
    font-family: var(--font-family);
    color: var(--color-text);
}
.form-input:focus { border-color: var(--color-primary); outline: none; }
textarea.form-input {
    min-height: 120px;
    line-height: 1.5;
    resize: vertical;
}
.form-label-hint {
    color: var(--color-text-light);
    font-weight: 400;
    font-size: 0.85rem;
}

.login-form { margin: 24px 0; }
.login-note {
    color: var(--color-text-light);
    font-size: 0.85rem;
    text-align: center;
}

/* ---------------------------------------------------------------------------
   Empty State
   --------------------------------------------------------------------------- */
.empty-state {
    text-align: center;
    padding: 32px 16px;
    color: var(--color-text-light);
    font-size: 1.1rem;
}

/* ---------------------------------------------------------------------------
   Lists index
   --------------------------------------------------------------------------- */
.page-subtitle {
    color: var(--color-text-light);
    margin-bottom: 24px;
}
/* Lists grid — compact horizontal cards matching .entity-tile so
   4-6 lists fit a mobile viewport instead of 1-2 (Brandon
   2026-06-26). Single-column on mobile, 2-col tablet, 3-col
   desktop. Same 88/96px heights as entity-tile for visual rhythm
   when stacking list pages next to /search and homepage tiles. */
.lists-grid {
    display: flex;
    flex-direction: column;
    gap: 8px;
}
@media (min-width: 769px) {
    .lists-grid {
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        gap: 12px;
    }
}
@media (min-width: 1024px) {
    .lists-grid {
        grid-template-columns: repeat(3, 1fr);
    }
}
.list-card {
    position: relative;
    display: flex;
    align-items: stretch;
    gap: 0;
    padding: 0;
    height: 88px;
    background: var(--color-white);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-card);
    color: var(--color-text);
    text-decoration: none;
    overflow: hidden;
    transition: border-color 0.2s, background 0.2s;
}
@media (min-width: 769px) {
    .list-card { height: 96px; }
}
a.list-card:hover,
button.list-card:hover {
    border-color: var(--color-primary);
    text-decoration: none;
    color: var(--color-text);
}
.list-detail-back {
    margin-bottom: 8px;
}
.list-detail-back a {
    color: var(--color-text-light);
    font-size: 0.9rem;
}
.list-detail-header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}
.list-visibility-control {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: 0.85rem;
    color: var(--color-text-light);
    margin-top: 4px;
}
/* List-page heading: compact vertical rhythm on mobile. The
   description, tag row, count, and visibility stack — tightening
   their gaps brings the toolbar (and the actual list contents)
   higher on the page (Brandon 2026-06-26). */
@media (max-width: 600px) {
    .list-item-count { margin-top: 4px; font-size: 0.78rem; }
    .list-visibility-control { font-size: 0.78rem; margin-top: 4px; }
    .list-visibility-control select { padding: 2px 6px; font-size: 0.78rem; }
}
.list-visibility-control select {
    font-size: 0.85rem;
    padding: 4px 8px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-white);
    cursor: pointer;
}
.list-visibility-badge {
    display: inline-block;
    padding: 1px 6px;
    border-radius: var(--radius);
    background: #ECEFF1;
    color: var(--color-text-light);
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
/* Square thumb on the left — matches .entity-tile-thumb dimensions
   so list cards share the same visual rhythm as restaurant + item
   tiles across the site. */
.list-card-image {
    width: 88px;
    height: 88px;
    flex-shrink: 0;
    overflow: hidden;
    background: var(--color-surface);
}
@media (min-width: 769px) {
    .list-card-image { width: 96px; height: 96px; }
}
.list-card-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.list-card-image-empty {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: linear-gradient(135deg, #FFF3E0, #FFE0B2);
    font-size: 1.6rem;
}
/* Body: title → optional description → count. Description only
   renders on the public browse page; hidden on mobile in either
   case so the card stays compact. */
.list-card-body {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 2px;
    padding: 8px 12px;
    text-align: left;
}
.list-card-body h2 {
    font-size: 1rem;
    font-weight: 700;
    margin: 0;
    line-height: 1.2;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.list-card-count {
    color: var(--color-text-light);
    font-size: 0.82rem;
    margin: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.list-card-teaser {
    border-style: dashed;
    background: #FAFAFA;
}
/* "+ New list" tile — button variant of list-card-teaser, used by
   admins/editors (and eventually paying customers) who can create
   custom lists. (#248 Tier A) */
.list-card-create {
    border-color: var(--color-primary);
    background: var(--color-primary-tint, #fff3f1);
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
    width: 100%;
}
.list-card-create:hover {
    background: #ffe5e0;
}
.list-card-create .list-card-image-teaser {
    background: linear-gradient(135deg, var(--color-primary-tint, #ffe5e0), #ffd6cf);
    color: var(--color-primary);
}

/* Save + Share icon buttons sit inline with the list title h1
   (Brandon 2026-06-26). Layout: 3-column grid (spacer | title |
   actions) so the title is centered between the page edges with
   the actions justified right — mirrors the visual weight of
   .restaurant-name-row without compromising title centering. */
.list-name-row {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: 10px;
}
.list-name-row h1 {
    margin: 0;
    grid-column: 2;
    text-align: center;
}
.list-name-actions {
    grid-column: 3;
    justify-self: end;
    display: flex;
    gap: 6px;
}
.list-name-action {
    flex-shrink: 0;
}
/* Saved-state for the heart icon — matches the .in-list visual
   on .btn-list-add (tint background, primary border) used on
   restaurant/menu-item bookmarks. The SVG fill is flipped via JS
   so the heart reads as filled when saved. */
.list-name-action.in-list {
    background: var(--color-primary-tint, #ffe5e0);
    border-color: var(--color-primary);
    color: var(--color-primary);
}
.list-name-action[disabled] {
    opacity: 0.55;
    cursor: not-allowed;
}
.list-name-action[disabled]:hover { background: transparent; }

/* Share modal — copy-link row + platform grid. (#248 Tier A) */
.list-share-url-row {
    display: flex;
    gap: 6px;
    align-items: stretch;
}
.list-share-url-row input {
    flex: 1;
    font-size: 0.85rem;
}
.list-share-platform-label {
    margin: 16px 0 8px;
    color: var(--color-text-light);
    font-size: 0.85rem;
    text-align: center;
}
.list-share-platforms {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(90px, 1fr));
    gap: 8px;
}
.list-share-platform {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    padding: 10px 6px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    color: var(--color-text);
    text-decoration: none;
    font-size: 0.78rem;
    background: var(--color-white);
    transition: background 0.1s, border-color 0.1s, transform 0.1s;
}
.list-share-platform:hover {
    background: var(--color-bg);
    border-color: var(--color-text-light);
    transform: translateY(-1px);
    text-decoration: none;
}
.list-share-platform-icon {
    font-size: 1.3rem;
    line-height: 1;
}
.list-card-image-teaser {
    background: linear-gradient(135deg, #ECEFF1, #CFD8DC);
    color: var(--color-text-light);
    /* Shrunk from 3rem to fit the new 88×88/96×96 compact thumb
       so the "+" doesn't overflow (Brandon 2026-06-26). */
    font-size: 2rem;
    font-weight: 200;
    display: flex;
    align-items: center;
    justify-content: center;
}
.list-card-cta {
    margin: 8px 0 0;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--color-primary);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

/* ---------------------------------------------------------------------------
   Flash Messages
   --------------------------------------------------------------------------- */
.flash {
    max-width: var(--max-width-wide);
    margin: 12px auto;
    padding: 12px 16px;
    border-radius: var(--radius);
    font-weight: 500;
    font-size: 0.9rem;
}
.flash a { color: inherit; text-decoration: underline; }
.flash-success { background: #E8F5E9; color: var(--color-success); border: 1px solid #A5D6A7; }
.flash-error { background: #FFEBEE; color: var(--color-error); border: 1px solid #EF9A9A; }
.flash-warning { background: #FFF8E1; color: #8A6D00; border: 1px solid #FFE082; }
.verify-banner-resend {
    display: inline-block;
    margin-left: 12px;
    padding: 4px 12px;
    background: #8A6D00;
    color: var(--color-white) !important;
    border-radius: var(--radius);
    text-decoration: none !important;
    font-size: 0.85rem;
    font-weight: 600;
}
.verify-banner-resend:hover { background: #6d5500; }

/* ---------------------------------------------------------------------------
   Footer
   --------------------------------------------------------------------------- */
.site-footer {
    background: var(--color-footer);
    color: var(--color-white);
    text-align: center;
    padding: 32px 16px 24px;
}

.footer-nav {
    display: flex;
    justify-content: center;
    gap: 24px;
    margin-bottom: 20px;
}
.footer-nav a {
    color: var(--color-white);
    font-size: 0.85rem;
    font-weight: 600;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}
.footer-nav a:hover { color: var(--color-primary-light); }

.footer-social {
    display: flex;
    justify-content: center;
    gap: 16px;
    margin-bottom: 20px;
}
.footer-social a {
    color: var(--color-white);
    display: flex;
    align-items: center;
    transition: color 0.15s;
}
.footer-social a:hover { color: var(--color-primary-light); }

.footer-legal {
    margin-bottom: 12px;
    font-size: 0.8rem;
}
.footer-legal a { color: var(--color-white); }
.footer-legal a:hover { color: var(--color-primary-light); }
.footer-divider {
    margin: 0 8px;
    opacity: 0.5;
}

.footer-copyright {
    font-size: 0.8rem;
    opacity: 0.7;
}

/* Version stamp (#133) — tiny grey link in the footer. Links to
   /version.json; title attribute carries env + short SHA. */
.site-version {
    margin-top: 8px;
    font-size: 0.7rem;
    opacity: 0.5;
    font-variant-numeric: tabular-nums;
}
.site-version a {
    color: inherit;
    text-decoration: none;
}
.site-version a:hover {
    opacity: 1;
    text-decoration: underline;
}

/* ---------------------------------------------------------------------------
   Responsive — Tablet+
   --------------------------------------------------------------------------- */
@media (min-width: 641px) {
    .hero h1 { font-size: 2.5rem; }
    .hero-subtitle { font-size: 1.1rem; }

    .two-col { flex-direction: row; align-items: center; }
    .two-col > * { flex: 1; }
    .two-col.reverse { flex-direction: row-reverse; }

    .circle-grid {
        grid-template-columns: repeat(3, 1fr);
        max-width: 480px;
    }

    .restaurant-grid {
        grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    }
}

@media (max-width: 640px) {
    .search-menu-icon { display: flex; }
    .menu-item { flex-direction: column; }
    .menu-item-actions { margin-left: 0; margin-top: 8px; }
    .venue-grid { grid-template-columns: repeat(2, 1fr); gap: 12px; }
    .search-item-row { flex-wrap: wrap; }
    .search-item-price { margin-left: auto; }
}

/* ---------------------------------------------------------------------------
   Homepage Sections — sit on the gray body surface; their content
   (cards, tiles, stat strips) provides the visual structure.
   --------------------------------------------------------------------------- */
/* Tighter vertical rhythm between sections (Brandon 2026-07-02).
   Was 12/14px, felt too loose given each section's own internal
   card padding also adds vertical space. Halving it to 6/8 keeps
   sections distinct without eating fold real estate. */
.home-section {
    padding: 6px 0;
}
.home-section-cta {
    text-align: center;
    margin-top: 12px;
}
@media (min-width: 769px) {
    .home-section {
        padding: 8px 0;
    }
}

/* Homepage hero — mobile-first vertical stack. On desktop it splits
   60/40 with text on the left and a 3-photo collage on the right. */
.home-hero {
    padding: 0 0 12px;
}
.home-hero-wrap {
    display: flex;
    flex-direction: column;
    gap: 32px;
    align-items: stretch;
}
.home-hero-text {
    text-align: left;
    /* Small inset so the eyebrow + title visually align with the
       search bar's text above (pill curvature + 4px input padding
       made the hero look further-left at 0 inset). The 8px adds to
       the .content-container's mobile 8px padding for 16px total
       from the screen edge — comfortable mobile read inset. */
    padding: 0 8px;
}
@media (min-width: 600px) {
    .home-hero-text {
        padding: 0;
    }
}
.home-hero-eyebrow {
    display: inline-flex;
    align-items: center;
    font-family: var(--font-family-heading);
    font-size: 1rem;
    font-weight: 600;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--color-primary);
    margin: 0 0 18px;
}
.home-hero-eyebrow::after {
    content: '';
    display: inline-block;
    width: 48px;
    height: 3px;
    margin-left: 12px;
    background: var(--color-primary);
    border-radius: 2px;
}
.home-hero-title {
    font-size: 2.3rem;
    line-height: 1.08;
    font-weight: 800;
    letter-spacing: -0.015em;
    color: var(--color-header);
    margin: 0 0 16px;
}
.home-hero-accent {
    position: relative;
    display: inline-block;
    color: var(--color-header);
}
.home-hero-underline {
    position: absolute;
    left: 0;
    right: 0;
    bottom: -6px;
    width: 100%;
    height: 12px;
    color: var(--color-primary);
    pointer-events: none;
}
.home-hero-subtitle {
    font-size: 1rem;
    line-height: 1.55;
    color: var(--color-text-light);
    max-width: 460px;
    margin: 0 0 22px;
}
.home-hero-subtitle-accent {
    color: var(--color-primary);
    font-weight: 700;
}
.home-hero-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 12px;
}
.home-hero-actions .btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 12px 22px;
}
.home-hero-cta-primary svg,
.home-hero-cta-secondary svg {
    flex-shrink: 0;
}

/* Photo collage — three rotated/overlapping cards positioned
   absolutely inside a flex slot. Heights driven by the column
   itself, so the collage scales with the available width. */
.home-hero-collage {
    position: relative;
    width: 86%;
    max-width: 480px;
    margin: 0 auto;
    height: 0;
    padding-bottom: 60%; /* aspect ratio of the collage box on mobile */
    color: var(--color-primary);
}
.home-hero-photo {
    position: absolute;
    border-radius: var(--radius-lg);
    overflow: hidden;
    background: var(--color-bg-light);
    border: 8px solid var(--color-white);
    box-shadow: 0 12px 28px rgba(13, 43, 82, 0.18);
}
.home-hero-photo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
/* Photos enlarged + positioned to overlap each other significantly,
   matching the mockup's polaroid-stack feel. Each one extends past
   the next so the eye reads them as a unified cluster. */
.home-hero-photo-1 {
    top: 6%;
    left: 0;
    width: 66%;
    height: 82%;
    transform: rotate(-5deg);
    z-index: 2;
}
.home-hero-photo-2 {
    top: -2%;
    right: -2%;
    width: 56%;
    height: 60%;
    transform: rotate(7deg);
    z-index: 1;
}
.home-hero-photo-3 {
    bottom: -4%;
    right: 0;
    width: 60%;
    height: 56%;
    transform: rotate(4deg);
    z-index: 3;
}
/* Fixed coral badge — anchored to the upper-left of the collage so
   it doesn't sit in the middle competing with the photos. Acts like
   a sticker peeking out from behind photo 1. */
.home-hero-badge {
    position: absolute;
    left: -6%;
    top: 40%;
    width: 110px;
    height: 110px;
    border-radius: 50%;
    background: var(--color-primary);
    color: var(--color-white);
    border: 7px solid var(--color-white);
    box-shadow: 0 12px 24px rgba(255, 90, 71, 0.4);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transform: rotate(-8deg);
    z-index: 5;
}
@media (max-width: 768px) {
    .home-hero-badge {
        width: 64px;
        height: 64px;
        border-width: 5px;
        box-shadow: 0 8px 18px rgba(255, 90, 71, 0.4);
    }
}
.home-hero-badge svg {
    width: 60%;
    height: 60%;
    display: block;
}

/* Decorative SVG accents sprinkled around the collage — coral stars
   and small expression-line clusters that read like comic-book
   motion marks, giving the section its "fun & whimsical" energy. */
.home-hero-deco {
    position: absolute;
    color: var(--color-primary);
    pointer-events: none;
    z-index: 5;
    display: block;
}
.home-hero-deco svg {
    display: block;
    width: 100%;
    height: 100%;
}
/* Whimsy decorations — bigger, two-color (coral + navy), more of them.
   Coral carries the brand energy; navy adds editorial counterweight
   matching the mockup's mix. Per-decoration position/size/color/rotation
   are emitted as inline styles by the index template, randomized in
   index.php so each pageload is a fresh arrangement (same effect as the
   hero collage's per-load photo shuffle). */
.home-hero-star { color: var(--color-primary); }
.home-hero-lines { color: var(--color-primary); opacity: 0.9; }

/* Mobile: hide the trailing decorations so the small-screen collage
   reads ~40% lighter. Bands are shuffled per-pageload in PHP so the
   subset that's hidden varies — keeps the layout feeling fresh
   without the small-screen clutter. */
@media (max-width: 768px) {
    .home-hero-star-i5,
    .home-hero-star-i6,
    .home-hero-star-i7,
    .home-hero-star-i8,
    .home-hero-lines-i3,
    .home-hero-lines-i4 {
        display: none;
    }
}

@media (min-width: 769px) {
    .home-hero {
        padding: 10px 0 18px;
    }
    .home-hero-wrap {
        flex-direction: row;
        align-items: stretch;
        gap: 48px;
    }
    .home-hero-text {
        flex: 1 1 56%;
        display: flex;
        flex-direction: column;
    }
    /* Push the trust strip to the bottom of the text column so it
       lines up with the bottom of the collage on the right. */
    .home-hero-text .home-hero-trust {
        margin-top: auto;
    }
    .home-hero-collage {
        flex: 0 0 42%;
        width: auto;
        max-width: none;
        margin: 0;
        padding-bottom: 0;
        height: 520px;
    }
    .home-hero-title {
        font-size: 3.1rem;
    }
    /* Small top breathing room above the eyebrow on desktop only —
       helps the column visually balance with the collage when the
       trust strip is pinned to the bottom. On mobile this would
       create asymmetric spacing below the search bar. */
    .home-hero-eyebrow {
        margin-top: 12px;
    }
}

/* Homepage search bar — narrow centered pill that sits just under
   the header (above the hero). Coral icon + accent on focus, neutral
   divider between input and the All-Parks filter chip. */
.home-searchbar-section {
    padding: 20px 0;
}
/* Mobile only: the shared .content-container adds its own 24px
   top/bottom which would stack on top of the section padding above
   and (via the neighbouring hero's container) below — collapse them
   so the 20px section padding is the only spacing around the search
   bar. Desktop keeps the container padding for editorial breathing
   room. */
@media (max-width: 768px) {
    .home-searchbar-section > .content-container,
    .home-hero > .content-container {
        padding-top: 0;
        padding-bottom: 0;
    }
}
@media (min-width: 769px) {
    .home-searchbar-section {
        padding: 14px 0 0;
    }
}
/* Homepage search bar mirrors /search's toolbar input-group (#147
   followup, Brandon 2026-06-18). The form itself just constrains
   width and centres; the input-group inside owns the visual chrome
   so swapping the /search look applies here automatically. */
.home-searchbar-form {
    max-width: 640px;
    margin: 0 auto;
}

/* Filter-select popup option rendering. Chrome inherits font /
   color / background from the <select> trigger into each <option>
   in the popup, so two selects with different trigger styling
   produce visually different popups even when option padding is
   identical. Reset the font + color + background here so popup
   options look uniform across the site. Right padding is more
   generous than left to handle browsers that size the popup
   tightly to the option text. Safari largely ignores this —
   acceptable; falls back to system. */
.filter-select option,
select.form-input option {
    padding: 6px 16px 6px 12px;
    font-family: var(--font-family);
    font-size: 0.875rem;
    font-weight: normal;
    color: var(--color-text);
    background: var(--color-white);
}

/* Hero trust callouts — promoted into the hero left column. Stacked
   icon-over-label-over-subtitle, 4 across, no card backgrounds so the
   strip sits visually inside the hero block. */
.home-hero-trust {
    list-style: none;
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 12px 16px;
    margin: 40px 0 16px;
    padding: 0;
}
/* Hide the trust callouts on mobile — they restate the
   headline/subtitle and the vertical real estate is more valuable
   for the hero collage. They re-appear at desktop widths where the
   hero column has room to anchor them at the bottom. */
@media (max-width: 768px) {
    .home-hero-trust {
        display: none;
    }
}
@media (min-width: 769px) {
    .home-hero-trust {
        margin-top: 48px;
    }
}
.home-hero-trust-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 4px;
    min-width: 0;
}
.home-hero-trust-icon {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: var(--color-primary-tint);
    color: var(--color-primary);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 4px;
}
.home-hero-trust-icon img {
    width: 64%;
    height: 64%;
    object-fit: contain;
    display: block;
}
.home-hero-trust-label {
    font-family: var(--font-family-heading);
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--color-header);
    line-height: 1.2;
}
.home-hero-trust-sub {
    font-size: 0.78rem;
    color: var(--color-text-light);
    line-height: 1.3;
}
@media (min-width: 769px) {
    .home-hero-trust {
        grid-template-columns: repeat(4, 1fr);
        gap: 20px;
    }
}

/* Homepage park browse grid — image-prominent cards with a dark
   bottom-gradient overlay carrying the park name + count. */
.home-park-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 12px;
}
.home-park-card {
    display: block;
    position: relative;
    aspect-ratio: 3/2;
    border-radius: var(--radius-lg);
    overflow: hidden;
    background-color: var(--color-header);
    background-size: cover;
    background-position: center;
    color: var(--color-white);
    box-shadow: var(--shadow);
    transition: transform 0.15s, box-shadow 0.15s;
    text-decoration: none;
}
.home-park-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--shadow-hover);
    color: var(--color-white);
    text-decoration: none;
}
.home-park-card-body {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    padding: 14px 16px;
    background: linear-gradient(to top, rgba(0,0,0,0.75) 0%, rgba(0,0,0,0.15) 55%, transparent 100%);
}
.home-park-card-body h3 {
    font-size: 1rem;
    font-weight: 700;
    margin: 0 0 2px;
    color: var(--color-white);
    text-shadow: 0 1px 4px rgba(0, 0, 0, 0.55);
}
.home-park-card-count {
    font-size: 0.8rem;
    color: var(--color-white);
    opacity: 0.9;
    text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
}
@media (min-width: 481px) {
    .home-park-grid { grid-template-columns: repeat(3, 1fr); }
}
@media (min-width: 769px) {
    .home-park-grid { grid-template-columns: repeat(4, 1fr); }
}

/* Stats row — sits in a white card so the three big primary-color
   numbers feel like their own anchor block on the gray surface. */
.stats-section {
    padding: 8px 0;
}
.stats-grid {
    display: flex;
    justify-content: space-around;
    gap: 16px;
    padding: 18px 20px;
    background: var(--color-white);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
}
.stat-item {
    text-align: center;
}
.stat-number {
    display: block;
    font-size: 2rem;
    font-weight: 700;
    color: var(--color-primary);
    line-height: 1.2;
}
.stat-label {
    font-size: 0.85rem;
    color: var(--color-text-light);
    font-weight: 500;
}


/* Featured article — compact editorial card replacing the previous
   long two-column blocks. Image-left + body-right on desktop,
   stacked on mobile. Whole card is one anchor. */
.featured-article {
    display: flex;
    flex-direction: column;
    background: var(--color-white);
    border-radius: var(--radius-lg);
    overflow: hidden;
    box-shadow: var(--shadow);
    color: var(--color-text);
    text-decoration: none;
    transition: box-shadow 0.2s, transform 0.15s;
}
.featured-article:hover {
    box-shadow: var(--shadow-hover);
    transform: translateY(-2px);
    color: var(--color-text);
    text-decoration: none;
}
.featured-article-image {
    width: 100%;
    aspect-ratio: 16/10;
    overflow: hidden;
    background: var(--color-bg);
}
.featured-article-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.featured-article-body {
    padding: 18px 20px 20px;
}
.featured-article-eyebrow {
    margin: 0 0 8px;
    font-family: var(--font-family-heading);
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--color-primary);
}
.featured-article-title {
    margin: 0 0 8px;
    font-size: 1.2rem;
    font-weight: 700;
    line-height: 1.25;
    color: var(--color-header);
}
.featured-article-blurb {
    margin: 0 0 14px;
    font-size: 0.92rem;
    line-height: 1.5;
    color: var(--color-text-light);
}
.featured-article-cta {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-family: var(--font-family-heading);
    font-size: 0.9rem;
    font-weight: 600;
    color: var(--color-primary);
}
.featured-article:hover .featured-article-cta {
    color: var(--color-primary-dark);
}
@media (min-width: 769px) {
    .featured-article {
        flex-direction: row;
        align-items: stretch;
    }
    .featured-article-image {
        flex: 0 0 40%;
        aspect-ratio: auto;
    }
    .featured-article-body {
        flex: 1 1 60%;
        padding: 24px 28px;
        display: flex;
        flex-direction: column;
        justify-content: center;
    }
    .featured-article-title {
        font-size: 1.5rem;
    }
}

/* Secondary article cards — compact image-on-top tiles sitting in a
   2-column grid below the featured article. Image-on-top contrasts
   the featured article's image-left layout; no blurb keeps the
   section vertically tight. */
/* Secondary cards use a compact horizontal layout (thumbnail left,
   text right) so they clearly read as subordinate "digest" items
   below the full-width featured article. Earlier version had 16/9
   images at 50% container width — wider than the featured card's
   40%-wide image on desktop, inverting the hierarchy. Brandon
   flagged 2026-07-02. */
.secondary-articles {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 10px;
    margin-top: 14px;
}
.secondary-article {
    display: flex;
    flex-direction: row;
    align-items: stretch;
    background: var(--color-white);
    border-radius: var(--radius-md);
    overflow: hidden;
    box-shadow: var(--shadow-sm);
    color: var(--color-text);
    text-decoration: none;
    transition: box-shadow 0.2s, transform 0.15s;
}
.secondary-article:hover {
    box-shadow: var(--shadow);
    transform: translateY(-1px);
    color: var(--color-text);
    text-decoration: none;
}
.secondary-article-image {
    flex: 0 0 96px;
    overflow: hidden;
    background: var(--color-bg);
}
.secondary-article-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.secondary-article-body {
    flex: 1;
    min-width: 0;
    padding: 8px 12px;
    display: flex;
    flex-direction: column;
    justify-content: center;
}
.secondary-article-eyebrow {
    margin: 0 0 3px;
    font-family: var(--font-family-heading);
    font-size: 0.62rem;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--color-primary);
}
.secondary-article-title {
    margin: 0;
    font-size: 0.88rem;
    font-weight: 600;
    line-height: 1.3;
    color: var(--color-header);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
@media (max-width: 559px) {
    /* Stack on narrow screens; keep single-column secondary list. */
    .secondary-articles {
        grid-template-columns: 1fr;
        gap: 8px;
    }
}
@media (min-width: 769px) {
    .secondary-articles {
        gap: 14px;
        margin-top: 18px;
    }
    .secondary-article-image {
        flex-basis: 120px;
    }
    .secondary-article-body {
        padding: 10px 14px;
    }
    .secondary-article-eyebrow {
        font-size: 0.7rem;
    }
    .secondary-article-title {
        font-size: 1rem;
        -webkit-line-clamp: 2;
    }
}

/* ---------------------------------------------------------------------------
   Auth Modals
   --------------------------------------------------------------------------- */
.modal-overlay {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
}

.modal-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.5);
}

.modal-card {
    position: relative;
    background: var(--color-white);
    border-radius: var(--radius-lg);
    padding: 32px 24px;
    width: 100%;
    /* min() so on a 320px phone (95vw = 304px) the modal doesn't try to
       stretch to 420px and overflow the overlay's 16px padding. */
    max-width: min(420px, 95vw);
    max-height: 90vh;
    overflow-y: auto;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
    z-index: 1;
}

.hidden { display: none !important; }
.modal-card.hidden { display: none; }
.modal-overlay.hidden { display: none; }

.modal-close {
    position: absolute;
    top: 8px;
    right: 8px;
    background: none;
    border: none;
    font-size: 1.75rem;
    color: var(--color-text-light);
    cursor: pointer;
    line-height: 1;
    /* 8px padding + ~28px glyph ≈ 44px tap target (Apple recommended min). */
    padding: 8px;
}
.modal-close:hover { color: var(--color-text); }

.modal-card h2 {
    font-size: 1.5rem;
    font-weight: 700;
    margin-bottom: 20px;
    color: var(--color-text);
}

.modal-header-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 20px;
}
.modal-header-row h2 { margin-bottom: 0; }

.modal-error {
    background: #FFEBEE;
    color: var(--color-error);
    border: 1px solid #EF9A9A;
    padding: 10px 14px;
    border-radius: var(--radius);
    margin-bottom: 16px;
    font-size: 0.9rem;
}

.modal-success {
    background: #E8F5E9;
    color: var(--color-success);
    border: 1px solid #A5D6A7;
    padding: 10px 14px;
    border-radius: var(--radius);
    margin-bottom: 16px;
    font-size: 0.9rem;
}

/* Context line above a modal form ("For: Garden Salad at Crystal Palace")
   — used by the correction-report popup (#208 Phase A). */
.modal-context {
    margin: -8px 0 16px;
    color: var(--color-text-light);
    font-size: 0.92rem;
}

/* "What's the problem?" chooser modal — two stacked tall buttons, each
   with a heading + small descriptive line (#208 Phase A). */
.problem-chooser-option {
    margin: 0 0 12px;
    padding: 14px 16px;
    text-align: left;
    line-height: 1.3;
}
.problem-chooser-option small {
    color: var(--color-text-light);
    font-weight: 400;
}
.problem-chooser-option:last-child {
    margin-bottom: 0;
}

/* "Report a correction" trigger paragraph that sits above the
   data-attribution footer on restaurant + menu-item detail pages. */
.correction-trigger {
    margin: 16px 0 4px;
    color: var(--color-text-light);
    font-size: 0.88rem;
    text-align: center;
}
.correction-trigger a {
    color: var(--color-primary);
    text-decoration: none;
    margin-left: 4px;
}
.correction-trigger a:hover {
    text-decoration: underline;
}

.bug-report-btn {
    position: fixed;
    bottom: 16px;
    right: 16px;
    z-index: 90;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--color-primary);
    color: var(--color-white);
    border: none;
    border-radius: 999px;
    padding: 10px 16px;
    font-size: 0.85rem;
    font-weight: 600;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
    cursor: pointer;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.bug-report-btn:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
}
.bug-report-btn-icon { font-size: 1rem; line-height: 1; }
@media (max-width: 600px) {
    .bug-report-btn-label { display: none; }
    /* Collapsed icon-only on mobile, tucked tighter into the bottom-
       right corner so it doesn't overlap page content. */
    .bug-report-btn {
        padding: 10px;
        bottom: 4px;
        right: 8px;
    }
}

.modal-card .form-group { margin-bottom: 16px; }

.modal-card .btn-block {
    width: 100%;
    max-width: none;
    margin-top: 8px;
}

.modal-toggle {
    text-align: center;
    margin-top: 16px;
    font-size: 0.9rem;
    color: var(--color-text-light);
}
.modal-toggle a {
    color: var(--color-text-light);
    text-decoration: underline;
}
.modal-toggle a:hover { color: var(--color-primary); }

.modal-legal {
    margin-top: 20px;
    font-size: 0.75rem;
    color: var(--color-text-light);
    line-height: 1.5;
}
.modal-legal a {
    color: var(--color-text-light);
    text-decoration: underline;
}

.form-row-between {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 16px;
    font-size: 0.85rem;
}

/* UGC license acknowledgement block (#82.3). Required check on the
   review + photo submission forms so the user actively grants the
   license described in /terms § User Content. Slightly muted so it
   reads as a confirmation, not a primary input. */
.ugc-consent {
    margin-top: 14px;
    padding: 10px 12px;
    background: var(--color-bg);
    border-radius: var(--radius);
    font-size: 0.85rem;
    color: var(--color-text-light);
}
.ugc-consent .checkbox-label {
    align-items: flex-start;
    gap: 8px;
    line-height: 1.4;
}
.ugc-consent input[type="checkbox"] {
    margin-top: 2px;
    flex-shrink: 0;
}
.ugc-consent a {
    color: var(--color-primary);
    text-decoration: underline;
}

.checkbox-label {
    display: flex;
    align-items: center;
    gap: 6px;
    color: var(--color-text);
    cursor: pointer;
    font-weight: 400;
}

.text-link-sm {
    color: var(--color-text-light);
    text-decoration: underline;
    font-size: 0.85rem;
}
.text-link-sm:hover { color: var(--color-primary); }

/* ---------------------------------------------------------------------------
   Restaurant Detail — Hero
   --------------------------------------------------------------------------- */
.restaurant-hero {
    position: relative;
    width: 100%;
    max-height: 320px;
    overflow: hidden;
    background: var(--color-bg-light);
}
.restaurant-hero img {
    width: 100%;
    height: 320px;
    object-fit: cover;
    display: block;
}
.restaurant-hero-overlay {
    position: absolute;
    bottom: 12px;
    right: 16px;
}
.restaurant-hero-overlay .score-badge {
    width: 48px;
    height: 48px;
    font-size: 1rem;
    box-shadow: 0 2px 8px rgba(0,0,0,0.2);
}

/* ---------------------------------------------------------------------------
   Restaurant Detail — Menu Buttons & Links
   --------------------------------------------------------------------------- */
.menu-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 20px;
}
.menu-buttons .btn small {
    font-weight: 400;
    opacity: 0.7;
}

/* ---------------------------------------------------------------------------
   Restaurant Detail — Menu Buttons
   --------------------------------------------------------------------------- */
.restaurant-menu-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 20px;
}
.btn-menu-link {
    display: inline-block;
    padding: 12px 24px;
    background: var(--color-primary);
    color: var(--color-white);
    font-weight: 600;
    font-size: 0.95rem;
    border-radius: var(--radius-lg);
    text-decoration: none;
    transition: background 0.15s;
}
.btn-menu-link:hover {
    background: var(--color-primary-dark);
    color: var(--color-white);
    text-decoration: none;
}

/* ---------------------------------------------------------------------------
   Restaurant Detail — CTA Buttons
   --------------------------------------------------------------------------- */
.restaurant-ctas {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 24px;
}
.btn-cta-disney {
    display: inline-block;
    padding: 10px 20px;
    background: #FFC107;
    color: #212121;
    font-weight: 600;
    font-size: 0.9rem;
    border-radius: var(--radius-lg);
    text-decoration: none;
    transition: background 0.15s;
}
.btn-cta-disney:hover {
    background: #FFD54F;
    color: #212121;
    text-decoration: none;
}

/* ---------------------------------------------------------------------------
   Restaurant Detail — Description
   --------------------------------------------------------------------------- */
.restaurant-description-section {
    margin-bottom: 24px;
    color: var(--color-text-light);
    line-height: 1.6;
}

/* ---------------------------------------------------------------------------
   Restaurant Detail — Sections
   --------------------------------------------------------------------------- */
.restaurant-section {
    padding-top: 24px;
    margin-top: 8px;
    border-top: 1px solid var(--color-border);
}
.restaurant-section h2 {
    font-size: 1.2rem;
    font-weight: 700;
    margin-bottom: 16px;
}

/* (Old horizontal-scroll Popular Items chrome retired. Current
   pattern is .popular-items-row + .popular-item-card +
   .popular-item-thumb defined lower in this file, post-#106 port.) */

/* ---------------------------------------------------------------------------
   Restaurant Detail — Review list heading
   --------------------------------------------------------------------------- */
.review-list-heading {
    font-size: 1rem;
    font-weight: 600;
    margin: 20px 0 12px;
    color: var(--color-text);
}

.tab-panel { min-height: 120px; }

@media (min-width: 641px) {
    .restaurant-hero { max-height: 400px; }
    .restaurant-hero img { height: 400px; }
}

/* ---------------------------------------------------------------------------
   Restaurant Menu Page
   --------------------------------------------------------------------------- */
.menu-toggle-bar {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
    margin-bottom: 24px;
}
.menu-toggle-btn {
    padding: 8px 16px;
    border: 2px solid var(--color-border);
    border-radius: var(--radius-lg);
    background: var(--color-white);
    font-family: var(--font-family);
    font-size: 0.9rem;
    font-weight: 500;
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s, color 0.15s;
}
.menu-toggle-btn:hover {
    border-color: var(--color-primary);
    color: var(--color-primary);
}
.menu-toggle-btn.active {
    border-color: var(--color-primary);
    background: var(--color-primary);
    color: var(--color-white);
}
.menu-toggle-btn small {
    font-weight: 400;
    opacity: 0.8;
}
.menu-toggle-style {
    display: inline-block;
    margin-left: 6px;
    padding: 2px 6px;
    font-size: 0.7rem;
    font-weight: 600;
    border-radius: var(--radius);
    background: #FFF3E0;
    color: #E65100;
    vertical-align: middle;
}

.menu-info-card {
    background: #FFF8F0;
    border: 1px solid #F0D8B8;
    border-radius: var(--radius-lg);
    padding: 16px 20px;
    margin-bottom: 24px;
}
.badge-menu-style {
    display: inline-block;
    font-size: 0.75rem;
    font-weight: 600;
    padding: 3px 10px;
    border-radius: var(--radius);
    background: #FFF3E0;
    color: #E65100;
    margin-bottom: 8px;
}
.menu-price-note {
    font-weight: 600;
    font-size: 1rem;
    color: var(--color-primary-dark);
    margin-bottom: 4px;
}
.menu-instructions {
    font-size: 0.9rem;
    color: var(--color-text-light);
    line-height: 1.5;
}

/* The old Food/Drinks/Snacks bucket-accordion layout
   (.menu-bucket-block, .menu-category-block, .menu-course-block,
   .menu-drink-summary, .bucket-chevron) was retired in #99 when
   the menu page ported to mirroring Disney's sections directly.
   See .menu-section-block / .menu-section-summary lower in this
   file for the current accordion chrome. */

/* Filter pills — used by the menu-page filter panel. Scoped to
   .menu-filter-pills so the rules don't leak onto the search-page
   <details class="filter-pill"> elements (#132 D7). */
.menu-filter-pills .filter-pill {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px 10px;
    font-size: 0.8rem;
    border: 1px solid var(--color-border, #ddd);
    border-radius: 999px;
    background: var(--color-white);
    color: var(--color-text);
    cursor: pointer;
    transition: background 0.15s, border-color 0.15s, color 0.15s;
    font-family: var(--font-family);
}
.menu-filter-pills .filter-pill:hover {
    border-color: var(--color-primary);
}
.menu-filter-pills .filter-pill.active {
    background: var(--color-primary);
    color: var(--color-white);
    border-color: var(--color-primary);
}
.menu-filter-pills .filter-pill-clear {
    padding: 4px 10px;
    font-size: 0.8rem;
    background: none;
    border: none;
    color: var(--color-text-light);
    cursor: pointer;
    text-decoration: underline;
    font-family: var(--font-family);
}

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}
/* Dense menu-item tile (#40) — goal: ~8 items per phone screen,
   scannable like a printed menu. Single-line truncation on name +
   description; price + score share the footer row. The save (+)
   button floats absolute in the card's top-right corner so the
   footer has room for the rating to grow into. */
/* Older .menu-item-card "dense tile" rules from #40 retired — the
   menu page now uses the flush-thumb / horizontal-line-separator
   layout defined further down (canonical .menu-item-card block).
   The old rules leaked background + border-radius + box-shadow
   into the new design, making each card look like a floating
   rounded chip with no spacing between them (Brandon 2026-06-19).
   Same cleanup as PR #172 — reverted with #177, re-applied. */

/* (Old dense-tile menu item chrome — .menu-item-thumb sizing,
   .menu-item-card-body/header/footer, .item-price-*, .score-decimal,
   .menu-page-back, .menu-toggle-* — retired with the #99 mirror
   port. Current .menu-item-card geometry lives lower in this file.) */

/* ---------------------------------------------------------------------------
   Menu Item Detail Page
   --------------------------------------------------------------------------- */

/* Image Carousel */
.item-carousel {
    position: relative;
    width: 100%;
    overflow: hidden;
    margin-bottom: 0;
    background: var(--color-bg-light);
}
.item-carousel-track {
    display: flex;
    align-items: center;
    transition: transform 0.4s ease;
    gap: 8px;
    padding: 16px 0;
}
.item-carousel-slide {
    position: relative;  /* anchors the attribution badge (#76 Phase 4) */
    min-width: 60%;
    max-width: 60%;
    flex-shrink: 0;
    transition: transform 0.4s ease, opacity 0.4s ease;
    opacity: 0.5;
    transform: scale(0.85);
    border-radius: var(--radius-lg);
    overflow: hidden;
}
.item-carousel-slide.active {
    opacity: 1;
    transform: scale(1);
    z-index: 1;
}
.item-carousel-slide img {
    width: 100%;
    max-height: 350px;
    object-fit: contain;
    display: block;
}
@media (min-width: 641px) {
    .item-carousel-slide {
        min-width: 50%;
        max-width: 50%;
    }
}
.carousel-btn {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    background: rgba(0, 0, 0, 0.45);
    color: var(--color-white);
    border: none;
    font-size: 2rem;
    line-height: 1;
    width: 44px;
    height: 44px;
    border-radius: 50%;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background 0.2s;
    z-index: 2;
}
.carousel-btn:hover { background: rgba(0, 0, 0, 0.7); }
.carousel-prev { left: 12px; }
.carousel-next { right: 12px; }
.carousel-dots {
    position: absolute;
    bottom: 12px;
    left: 50%;
    transform: translateX(-50%);
    display: flex;
    gap: 8px;
    z-index: 2;
}
.carousel-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    border: 2px solid var(--color-white);
    background: transparent;
    cursor: pointer;
    padding: 0;
    transition: background 0.2s;
}
.carousel-dot.active {
    background: var(--color-white);
}

/* Compact carousel variant for the restaurant page (#36) — short
   strip below the summary instead of a full-height hero up top. */
.item-carousel-compact {
    margin: 16px 0 24px;
    border-radius: var(--radius-lg);
}
.item-carousel-compact .item-carousel-track {
    padding: 0;
    gap: 0;
}
.item-carousel-compact .item-carousel-slide {
    min-width: 100%;
    max-width: 100%;
    opacity: 1;
    transform: none;
    border-radius: var(--radius-lg);
}
.item-carousel-compact .item-carousel-slide img {
    max-height: 200px;
    object-fit: cover;
    width: 100%;
}
.item-carousel-compact .carousel-btn {
    width: 36px;
    height: 36px;
    font-size: 1.4rem;
}

/* Image attribution badge (#76 Phase 4) — small pill anchored to the
   bottom-right corner of every food/restaurant photo so guests can
   tell at a glance whether they're looking at Disney's official
   imagery, a TPF staff upload, or a real photo a user submitted.
   User badges link to /u/{username}.

   Auto-hidden at < 200px container width — too small to read without
   obscuring the photo. The relevant photo container (e.g.
   .item-carousel-slide) must be `position: relative` for anchoring. */
.image-attribution {
    position: absolute;
    bottom: 6px;
    right: 6px;
    z-index: 2;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px 8px;
    background: rgba(0, 0, 0, 0.55);
    color: var(--color-white);
    font-size: 0.72rem;
    font-weight: 500;
    line-height: 1;
    border-radius: var(--radius-lg);
    text-decoration: none;
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
    max-width: calc(100% - 12px);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.image-attribution:hover {
    background: rgba(0, 0, 0, 0.75);
    color: var(--color-white);
}
.image-attribution-disney  { /* default neutral — Disney first-party is the most common */ }
.image-attribution-staff   { background: rgba(255, 90, 71, 0.85); /* coral for TPF staff */ }
.image-attribution-user    { /* default neutral */ }

/* Camera glyph for both attribution chips. Inline SVG via
   background-image renders with consistent baseline against the
   text — the 📷 emoji we used before sat low because emoji glyph
   metrics differ from Latin text. Sized 11×11 so it doesn't
   overpower the chip text. */
.image-attribution::before,
.restaurant-carousel-attribution::before {
    content: '';
    display: inline-block;
    width: 11px;
    height: 11px;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z'/><circle cx='12' cy='13' r='4'/></svg>");
    background-repeat: no-repeat;
    background-position: center;
    background-size: contain;
    flex-shrink: 0;
}

/* Hide badge on small thumbnails — readability over information density. */
/* Suppress chip on entity-tile thumbs — too small to read
   alongside a 88px square. The Guest Photos gallery now wants
   the chip to surface (Brandon 2026-06-19), so it's been removed
   from this rule. */
.entity-tile-thumb .image-attribution {
    display: none;
}
@media (max-width: 480px) {
    .image-attribution {
        font-size: 0.68rem;
        padding: 2px 6px;
    }
}

/* Photo empty-state (#76 Phase 3) — renders in place of the carousel
   when a menu item or restaurant has no real photos. Copy + CTA invite
   contributions; never reads as "broken" or "missing". Same height
   footprint as the carousel so the page rhythm stays consistent. */
.photo-empty-state {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 28px 16px;
    margin: 20px auto;
    max-width: 480px;
    min-height: 180px;
    background: var(--color-bg);
    border: 1px dashed var(--color-border);
    border-radius: var(--radius-lg);
}
.photo-empty-state-icon {
    font-size: 2rem;
    margin-bottom: 8px;
    opacity: 0.7;
}
.photo-empty-state-heading {
    font-size: 1rem;
    font-weight: 600;
    color: var(--color-header);
    margin: 0 0 6px;
}
.photo-empty-state-body {
    font-size: 0.9rem;
    color: var(--color-text-light);
    margin: 0 0 14px;
    max-width: 320px;
    line-height: 1.4;
}
.photo-empty-state-cta {
    padding: 8px 18px;
}
.photo-empty-state-secondary {
    margin: 0;
    font-size: 0.9rem;
    color: var(--color-text-light);
}
.photo-empty-state-secondary a {
    color: var(--color-primary);
    text-decoration: underline;
}
.item-carousel-compact .carousel-dots {
    bottom: 8px;
}
@media (min-width: 641px) {
    .item-carousel-compact .item-carousel-slide img { max-height: 260px; }
}

/* Item summary tags — small pill row above the menu item description
   (price/cuisine/course/rating). Used by templates/menu_item.html.
   Was previously bundled with .restaurant-summary-tags from the old
   restaurant page layout; that family removed in the #99/#106 cleanup
   pass since the new restaurant page uses .restaurant-tags instead. */
.item-summary-tags {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 6px;
    margin-bottom: 12px;
}
@media (max-width: 600px) {
    .item-summary-tags {
        gap: 5px;
        margin-bottom: 10px;
    }
}

/* Source attribution footer (#74 Phase 5). Quiet single-line credit
   at the bottom of restaurant pages for community-maintained venues
   so guests calibrate trust appropriately. Default Disney-API rows
   don't show this. */
.source-attribution {
    margin: 32px 0 16px;
    padding: 12px 16px;
    background: var(--color-bg);
    border-left: 3px solid var(--color-secondary);
    border-radius: 0 var(--radius) var(--radius) 0;
    font-size: 0.85rem;
    color: var(--color-text-light);
    line-height: 1.5;
}
.source-attribution a {
    color: var(--color-primary);
    text-decoration: underline;
}

/* Section spacing for vertical flow layout */
.item-section {
    margin-bottom: 32px;
    padding-top: 8px;
}
.item-section h2 {
    font-size: 1.25rem;
    font-weight: 600;
    margin-bottom: 16px;
}

.item-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 16px;
    margin-bottom: 20px;
}
.item-header h1 {
    font-size: 1.75rem;
    font-weight: 600;
    margin: 0;
    flex: 1;
}
/* Info Grid */
.item-info-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
    gap: 16px;
    background: var(--color-bg-light);
    border-radius: var(--radius-lg);
    padding: 16px 20px;
    margin-bottom: 24px;
}
.info-grid-item {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.info-label {
    font-size: 0.75rem;
    font-weight: 600;
    color: var(--color-text-light);
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.info-value {
    font-size: 1rem;
    font-weight: 500;
    color: var(--color-text);
}
.info-value small {
    font-size: 0.8rem;
    color: var(--color-text-light);
    font-weight: 400;
    display: block;
    margin-top: 2px;
}
.info-value .score-badge-sm {
    margin-right: 8px;
}

/* Dietary Tags */
.dietary-tags-section {
    margin-bottom: 24px;
}
.dietary-tags-section h2 {
    font-size: 1.1rem;
    font-weight: 600;
    margin-bottom: 12px;
}
.dietary-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}
.dietary-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 0.85rem;
    font-weight: 500;
    padding: 6px 14px;
    border-radius: 999px;
}
.dietary-pill .dietary-icon {
    font-size: 1rem;
}

.item-description-full {
    font-size: 1rem;
    line-height: 1.7;
    color: var(--color-text);
}
/* Menu-item heading card (Brandon 2026-06-20). Two layouts driven
   by viewport:
     - Mobile (default): single column, .menu-item-header-side
       collapses to a footer strip with rating on the left, price
       right-aligned, "View Full Menu" CTA wrapping to its own row.
     - Desktop (>= 700px): two-column flex; side becomes the right
       column (rating → price → CTA stacked, right-aligned). */
.menu-item-header {
    display: flex;
    flex-direction: column;
}
.menu-item-header .menu-item-header-body {
    padding: 18px 20px 12px;
}
.menu-item-header-description {
    margin: 10px 0 0;
    font-size: 0.95rem;
    line-height: 1.55;
    color: var(--color-text);
}
/* Restaurant detail-page description — same visual treatment as
   the menu-item description for cross-page consistency
   (Brandon 2026-06-24). */
.restaurant-description {
    margin: 12px 0 0;
    font-size: 0.95rem;
    line-height: 1.55;
    color: var(--color-text);
}
.menu-item-header .restaurant-location {
    margin: 8px 0 0;
}
.menu-item-header-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 12px;
}
.menu-item-header .restaurant-tags {
    margin-top: 12px;
}
/* Mobile footer-strip layout for the side block. Grid keeps the
   rating + price on the same row, CTA on its own row below. */
.menu-item-header-side {
    border-top: 1px solid var(--color-border);
    padding: 12px 20px 14px;
    display: grid;
    grid-template-columns: 1fr auto;
    column-gap: 12px;
    row-gap: 10px;
    align-items: center;
}
.menu-item-header-rating-row {
    grid-column: 1;
    grid-row: 1;
    display: flex;
    /* Caption stacks below the pill so the full "% would order again
       · N ratings" line has the column width to itself, instead of
       riding alongside the pill and pushing off the right edge on
       narrow phones (Brandon 2026-06-23). */
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
}
.menu-item-header-price {
    grid-column: 2;
    grid-row: 1;
    font-size: 1.5rem;
    font-weight: 800;
    color: var(--color-primary-dark);
    font-variant-numeric: tabular-nums;
    line-height: 1;
    text-align: right;
}
.menu-item-header-cta {
    grid-column: 1 / -1;
    grid-row: 2;
}
.menu-item-header-cta .btn {
    width: 100%;
}
/* Mobile-only: center the vote pill + caption + price across the
   full side block, each on its own row (Brandon 2026-06-23). The
   default desktop/tablet layout shows rating on the left and price
   on the right — at mobile widths the price can't sit next to a
   full-width pill without crowding, so stack and center for
   visual harmony. */
@media (max-width: 600px) {
    .menu-item-header-rating-row {
        grid-column: 1 / -1;
        grid-row: 1;
        align-items: center;
        text-align: center;
    }
    .menu-item-header-price {
        grid-column: 1 / -1;
        grid-row: 2;
        text-align: center;
    }
    .menu-item-header-cta {
        grid-row: 3;
    }
}
/* Heading-card rating just upscales the no-pill .thumbs-badge —
   the pill-stripping overrides were retired when the base became
   no-pill globally (Brandon 2026-06-21). */
.menu-item-header-rating {
    font-size: 1.4rem;
    font-weight: 800;
    gap: 8px;
    padding: 8px 14px;
}
.menu-item-header-rating-num {
    font-variant-numeric: tabular-nums;
}

/* === Vote pill (#201 Phase 1, Brandon 2026-06-23) =====================
   YouTube-style one-tap quick vote on the menu-item heading.
   Structure: pill bubble containing [thumb-up button | divider |
   thumb-down button], aggregate % lives inside the thumb-up button.
   The bubble inherits .thumbs-badge tone classes for the resting
   background tint; .vote-pill-btn.is-active gets a tinted circle
   that highlights the user's selected vote. */
.vote-pill {
    display: inline-flex;
    align-items: center;
    gap: 0;
    padding: 2px;
    font-size: 1.4rem;
    font-weight: 800;
}
.vote-pill-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 6px 12px;
    border: none;
    background: transparent;
    color: inherit;
    font: inherit;
    cursor: pointer;
    border-radius: 999px;
    transition: background 0.15s, color 0.15s, transform 0.1s;
}
.vote-pill-btn:hover {
    background: rgba(0, 0, 0, 0.06);
}
.vote-pill-btn:active {
    transform: scale(0.96);
}
.vote-pill-divider {
    width: 1px;
    height: 22px;
    background: rgba(0, 0, 0, 0.15);
    margin: 0 2px;
}
.vote-pill-up.is-active {
    background: #c8e6c9;
    color: #1b5e20;
}
.vote-pill-down.is-active {
    background: #ffcdd2;
    color: #b71c1c;
}
.vote-pill-count {
    /* Reserve a stable width on each count so the pill doesn't
       jitter as votes tick across digit boundaries (0→1, 9→10,
       etc.) — single digits center inside the reserved space
       (Brandon 2026-06-23). Combined with tabular-nums the pill
       stays a fixed width through the typical soft-launch vote
       range; very large counts (≥4 chars) will still grow it. */
    display: inline-block;
    min-width: 2ch;
    text-align: center;
    font-variant-numeric: tabular-nums;
}

/* Prompt that nudges signed-out + signed-in-but-unvoted users back
   up to the heading thumbs. Sits in the Reviews section above any
   review list. */
.review-rate-prompt {
    margin: 0 0 12px;
    padding: 12px 16px;
    background: var(--color-bg);
    border-radius: var(--radius-card);
    color: var(--color-text-light);
    font-size: 0.92rem;
    text-align: center;
}
.review-rate-prompt a {
    color: var(--color-primary);
    font-weight: 600;
    text-decoration: none;
}
.review-rate-prompt a:hover {
    text-decoration: underline;
}
.menu-item-header-rating-count {
    color: var(--color-text-light);
    font-size: 0.85rem;
    white-space: nowrap;
}

/* Desktop layout — side becomes a right column inside the heading.
   Rating + price + CTA stack vertically right-aligned. */
@media (min-width: 700px) {
    .menu-item-header {
        flex-direction: row;
        align-items: stretch;
    }
    .menu-item-header .menu-item-header-body {
        flex: 1 1 auto;
        min-width: 0;
        padding: 18px 0 18px 20px;
    }
    .menu-item-header-side {
        flex: 0 0 auto;
        display: flex;
        flex-direction: column;
        align-items: flex-end;
        justify-content: flex-start;
        gap: 12px;
        padding: 18px 20px;
        border-top: none;
        border-left: 1px solid var(--color-border);
        min-width: 170px;
        text-align: right;
    }
    .menu-item-header-rating-row,
    .menu-item-header-price,
    .menu-item-header-cta {
        grid-column: auto;
        grid-row: auto;
    }
    /* Right-align the pill + caption inside the right column on
       desktop so the stack sits flush with the side gutter. */
    .menu-item-header-rating-row {
        align-items: flex-end;
        text-align: right;
    }
    .menu-item-header-rating {
        font-size: 1.3rem;
    }
    .menu-item-header-price {
        font-size: 1.4rem;
    }
    .menu-item-header-cta .btn {
        width: auto;
    }
}

/* === Menu-item review card (binary verdict) ============================
   Compact layout that swaps stars/body for a big tonal thumbs verdict
   on the right and the reviewer's chips below. No body text — written
   reviews are deferred behind paid features (Brandon 2026-06-20). */
.review-card-binary {
    padding: 14px 16px;
}
.review-card-binary .review-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}
.review-card-binary .review-author {
    min-width: 0;
    flex: 1 1 auto;
}
.review-verdict {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    border-radius: 50%;
}
.review-verdict-yes {
    background: #e8f5e9;
    color: #2e7d32;
}
.review-verdict-no {
    background: #ffebee;
    color: #c62828;
}
.review-card-binary .review-chips {
    margin-top: 10px;
}
/* Verified reviewer checkmark — coral so it reads as a brand
   trust signal instead of fading into the grey time stamp. */
.review-verified-badge {
    color: var(--color-primary-dark);
    font-weight: 800;
}
.empty-state-text {
    color: var(--color-text-light);
    font-style: italic;
}

/* Locations Served */
.locations-section {
    margin-bottom: 32px;
}
.locations-section h2 {
    font-size: 1.25rem;
    font-weight: 600;
    margin-bottom: 16px;
}
.locations-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 12px;
}
.location-card {
    display: block;
    background: var(--color-white);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    padding: 16px;
    text-decoration: none;
    color: var(--color-text);
    transition: box-shadow 0.2s, border-color 0.2s;
}
.location-card:hover {
    box-shadow: var(--shadow-hover);
    border-color: var(--color-primary);
    text-decoration: none;
}
.location-card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 8px;
}
.location-card-header h3 {
    font-size: 1rem;
    font-weight: 600;
    margin: 0;
}
.location-card-meta {
    display: flex;
    gap: 8px;
    font-size: 0.85rem;
    color: var(--color-text-light);
    margin-bottom: 8px;
}
.location-card-menu {
    display: flex;
    gap: 8px;
    margin-bottom: 8px;
}
.location-card-menus {
    display: flex;
    flex-direction: column;
    gap: 4px;
}
.location-card-menu-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}
.location-card-menu-row .price {
    font-weight: 600;
    color: var(--color-primary-dark);
}
.badge-menu {
    background: #E3F2FD;
    color: #1565C0;
}
.badge-meal {
    background: #F3E5F5;
    color: #7B1FA2;
}
.location-card-price {
    display: flex;
    align-items: baseline;
    gap: 8px;
}
.location-card-price .price {
    font-weight: 600;
    font-size: 1.1rem;
    color: var(--color-primary-dark);
}
.location-card-price .price-note {
    font-size: 0.8rem;
    color: var(--color-text-light);
    font-style: italic;
}

/* Nutrition Facts - FDA Style */
.nutrition-section {
    margin-bottom: 32px;
}
.nutrition-section h2 {
    font-size: 1.25rem;
    font-weight: 600;
    margin-bottom: 16px;
}
.nutrition-label {
    max-width: 320px;
    border: 1px solid var(--color-text);
    padding: 12px;
    background: var(--color-white);
    font-family: Helvetica, Arial, sans-serif;
}
.nutrition-header h3 {
    font-size: 1.75rem;
    font-weight: 900;
    margin: 0 0 4px 0;
    border-bottom: 1px solid var(--color-text);
    padding-bottom: 4px;
}
.nutrition-header p {
    margin: 2px 0;
    font-size: 0.9rem;
}
.nutrition-divider {
    border-top: 1px solid var(--color-text);
    margin: 4px 0;
}
.nutrition-divider.thick {
    border-top-width: 8px;
}
.nutrition-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 4px 0;
    font-size: 0.9rem;
}
.nutrition-row.calories {
    font-size: 1.5rem;
    font-weight: 900;
}
.nutrition-row.calories .nutrition-label-text {
    font-size: 1.5rem;
}
.nutrition-row.indent {
    padding-left: 16px;
}
.nutrition-label-text {
    font-weight: 600;
}
.nutrition-value {
    font-weight: 600;
}
.nutrition-row.vitamins {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 8px;
}
.vitamin-item {
    display: flex;
    justify-content: space-between;
}

/* Responsive */
@media (min-width: 641px) {
    .locations-grid {
        grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    }
    .item-info-grid {
        grid-template-columns: repeat(4, 1fr);
    }
}

/* Menu item links in restaurant menu */
.menu-item-link {
    color: var(--color-text);
    text-decoration: none;
}
.menu-item-link:hover {
    color: var(--color-primary);
    text-decoration: underline;
}
.menu-item-thumb a {
    display: block;
    width: 100%;
    height: 100%;
}

/* Make item names clickable */
.menu-item-card-header h3 a,
.menu-item-info h3 a,
.popular-card-body h3 a,
.search-item-info h3 a {
    color: var(--color-text);
    text-decoration: none;
}
.menu-item-card-header h3 a:hover,
.menu-item-info h3 a:hover,
.popular-card-body h3 a:hover,
.search-item-info h3 a:hover {
    color: var(--color-primary);
}

/* ---------------------------------------------------------------------------
   Reviews
   --------------------------------------------------------------------------- */
.tab-count {
    font-weight: 400;
    font-size: 0.85em;
    color: var(--color-text-light);
}

/* Sub-rating summary bars */
.sub-ratings-summary {
    margin-bottom: 24px;
    padding: 16px;
    background: var(--color-bg-light);
    border-radius: var(--radius-lg);
}
.sub-rating-row {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 8px;
}
.sub-rating-row:last-child { margin-bottom: 0; }
.sub-rating-label {
    font-size: 0.85rem;
    font-weight: 500;
    color: var(--color-text);
    min-width: 140px;
    flex-shrink: 0;
}
.sub-rating-bar-track {
    flex: 1;
    height: 8px;
    background: var(--color-border);
    border-radius: var(--radius);
    overflow: hidden;
}
.sub-rating-bar-fill {
    height: 100%;
    border-radius: var(--radius);
    transition: width 0.3s;
}
.sub-rating-bar-fill.score-green { background: var(--color-score-green); }
.sub-rating-bar-fill.score-yellow-green { background: var(--color-score-yellow-green); }
.sub-rating-bar-fill.score-yellow { background: var(--color-score-yellow); }
.sub-rating-bar-fill.score-orange { background: var(--color-score-orange); }
.sub-rating-bar-fill.score-red { background: var(--color-score-red); }
.sub-rating-value {
    font-size: 0.85rem;
    font-weight: 600;
    min-width: 28px;
    text-align: right;
}

/* Review card chrome lives in the new design-system block lower in
   this file (.review-list/.review-card/.review-head/.review-author/
   .review-author-text/.review-name/.review-verified-badge/.review-time/
   .review-rating/.review-chips/.review-body etc.). Old review CSS
   removed in the #99/#106 cleanup pass. */

.yes-no-toggle {
    display: flex;
    gap: 8px;
    max-width: 480px;
}

/* YouTube-style visual vote: two big circular thumb buttons in a
   single rounded pill (Brandon 2026-06-22). No text — the icons
   carry the meaning. Used on the menu-item review form in place of
   the older yes-no-toggle "Yes" / "No" buttons. */
.thumbs-vote-toggle {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px;
    background: #f1f3f4;
    border-radius: 999px;
}
.thumbs-vote-btn {
    width: 52px;
    height: 52px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    background: transparent;
    border: none;
    border-radius: 50%;
    color: var(--color-text-light);
    cursor: pointer;
    transition: background 0.12s, color 0.12s, transform 0.1s;
}
.thumbs-vote-btn:hover {
    background: rgba(0, 0, 0, 0.06);
    color: var(--color-text);
}
.thumbs-vote-btn:active {
    transform: scale(0.94);
}
.thumbs-vote-up.is-active {
    background: #e8f5e9;
    color: #2e7d32;
}
.thumbs-vote-down.is-active {
    background: #ffebee;
    color: #c62828;
}
.yes-no-btn {
    flex: 1;
    padding: 12px 16px;
    background: var(--color-white);
    border: 1.5px solid var(--color-border);
    border-radius: var(--radius-card);
    cursor: pointer;
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--color-text);
    transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.yes-no-btn:hover {
    border-color: var(--color-primary);
    color: var(--color-primary);
}
.yes-no-btn.is-active {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: var(--color-white);
}

.prompt-chip-row {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 10px;
}
.prompt-chip {
    padding: 5px 12px;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: 999px;
    cursor: pointer;
    font-size: 0.82rem;
    color: var(--color-text);
}
.prompt-chip:hover {
    border-color: var(--color-primary);
    color: var(--color-primary);
}

.char-counter {
    text-align: right;
    font-size: 0.78rem;
    color: var(--color-text-light);
    margin-top: 4px;
}
.char-counter.is-near-limit {
    color: var(--color-primary-dark);
    font-weight: 600;
}

.form-hint {
    font-size: 0.82rem;
    color: var(--color-text-light);
    margin: 0 0 6px;
}
.form-hint-inline {
    font-size: 0.85rem;
    color: var(--color-text-light);
    font-weight: 400;
}

/* Yes/No signal badges on review cards */
.review-signals {
    margin-top: 8px;
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
}
.review-signal {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 10px;
    border-radius: var(--radius-lg);
    font-size: 0.78rem;
    font-weight: 600;
}
.review-signal-yes {
    background: #E8F5E9;
    color: var(--color-success);
}
.review-signal-no {
    background: #FFEBEE;
    color: var(--color-error);
}
.score-input-row {
    display: flex;
    gap: 4px;
    margin-top: 6px;
}
.score-btn {
    width: 32px;
    height: 32px;
    border: 2px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-white);
    font-family: var(--font-family);
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
    color: var(--color-text-light);
    transition: background 0.1s, border-color 0.1s, color 0.1s;
}
.score-btn:hover {
    border-color: var(--color-primary);
    color: var(--color-primary);
}
.score-btn.active {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: var(--color-white);
}
.review-mode-toggle {
    display: inline-block;
    margin: 4px 0 16px;
    color: var(--color-text-light);
    font-size: 0.9rem;
    text-decoration: underline;
}
.review-mode-toggle:hover {
    color: var(--color-primary);
}
/* Interactive 5-star rating picker (#132 B1, per Dustin).
   Replaces the legacy 10-square widget. Each star covers two DB-scale
   units (0-10 storage stays the same), so the picker emits 10 distinct
   values 1.0 → 10.0 in 1.0 steps: left half = N*2-1, right half = N*2.
   Reuses the .star SVG mask for visuals so display and picker share
   the same star shape. */
.star-picker {
    display: inline-flex;
    gap: 6px;
    margin: 4px 0 0;
}
.star-picker-star {
    position: relative;
    width: 40px;
    height: 40px;
}
.star-picker-star .star {
    --star-size: 40px;
    pointer-events: none;
    display: block;
}
.star-picker-half {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 50%;
    margin: 0;
    padding: 0;
    border: 0;
    background: transparent;
    cursor: pointer;
}
.star-picker-half-left  { left: 0; }
.star-picker-half-right { right: 0; }
.star-picker-half:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 2px;
    border-radius: var(--radius);
}
@media (max-width: 600px) {
    .star-picker-star {
        width: 36px;
        height: 36px;
    }
    .star-picker-star .star {
        --star-size: 36px;
    }
}
.review-message {
    margin-top: 12px;
    padding: 10px 14px;
    border-radius: var(--radius);
    font-size: 0.9rem;
}
.review-message-success {
    background: #E8F5E9;
    color: var(--color-success);
    border: 1px solid #A5D6A7;
}
.review-message-error {
    background: #FFEBEE;
    color: var(--color-error);
    border: 1px solid #EF9A9A;
}
.review-login-prompt {
    text-align: center;
    padding: 24px;
    color: var(--color-text-light);
}
.review-login-prompt p {
    margin-bottom: 12px;
}

/* ---------------------------------------------------------------------------
   Legal & Contact Pages
   --------------------------------------------------------------------------- */
.legal-body {
    background: var(--color-white);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    padding: 20px 22px;
}
.legal-body h2 {
    font-size: 1.1rem;
    font-weight: 600;
    margin-top: 24px;
    margin-bottom: 8px;
    color: var(--color-header);
}
.legal-body h2:first-child {
    margin-top: 0;
}
.legal-body p {
    margin-bottom: 12px;
    line-height: 1.7;
    color: var(--color-text);
}
.legal-body ol,
.legal-body ul {
    padding-left: 1.6rem;
    margin: 0 0 12px;
    line-height: 1.7;
    color: var(--color-text);
}
.legal-body li {
    margin-bottom: 6px;
}
.legal-body li::marker {
    color: var(--color-text-light);
}
.legal-body blockquote {
    margin: 0 0 16px;
    padding: 12px 18px;
    border-left: 4px solid var(--color-primary);
    background: var(--color-bg);
    color: var(--color-text);
    border-radius: 0 var(--radius) var(--radius) 0;
}
.legal-body blockquote p:last-child {
    margin-bottom: 0;
}
.legal-body code {
    background: var(--color-bg);
    padding: 1px 6px;
    border-radius: var(--radius);
    font-size: 0.92em;
}
.legal-body pre {
    background: var(--color-bg);
    padding: 12px 14px;
    border-radius: var(--radius);
    overflow-x: auto;
    margin: 0 0 12px;
}
.legal-body pre code {
    background: transparent;
    padding: 0;
}
.legal-body hr {
    border: 0;
    border-top: 1px solid var(--color-border);
    margin: 20px 0;
}
.legal-body a {
    color: var(--color-primary);
}
.legal-body a:hover {
    color: var(--color-primary-dark);
}
.legal-body table {
    width: 100%;
    border-collapse: collapse;
    margin: 0 0 16px;
    font-size: 0.95em;
}
.legal-body th,
.legal-body td {
    padding: 9px 12px;
    border: 1px solid var(--color-border);
    text-align: left;
    vertical-align: top;
}
.legal-body thead th {
    background: var(--color-header);
    color: var(--color-bg);
    font-weight: 700;
}
.legal-body tbody tr:nth-child(even) td {
    background: var(--color-bg);
}

.contact-form {
    /* No max-width cap — let the form fill the .content-container
       (same pattern as .settings-form). Paired form-row fields keep
       individual inputs at a comfortable width on wider screens. */
    background: var(--color-white);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    padding: 20px 22px;
}
.contact-form .form-group {
    margin-bottom: 16px;
}
.contact-form label {
    display: block;
    font-weight: 500;
    margin-bottom: 4px;
    font-size: 0.9rem;
}
.contact-success {
    text-align: center;
    padding: 28px 20px;
}
.contact-success p {
    font-size: 1.1rem;
    margin-bottom: 16px;
    color: var(--color-success);
}

/* ---------------------------------------------------------------------------
   Settings Page
   --------------------------------------------------------------------------- */
.settings-section {
    margin-bottom: 16px;
    padding: 16px 20px 20px;
    background: var(--color-white);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
}
.settings-section .section-heading-card {
    margin-top: 0;
    margin-bottom: 16px;
}
.settings-form {
    /* No max-width cap — let the form fill the .settings-section
       container (which itself sits inside the .content-container's
       1100px max). Paired form-row fields keep individual inputs at
       a comfortable width on wider screens. */
}
.settings-form .form-group {
    margin-bottom: 16px;
}
.settings-form label {
    display: block;
    font-weight: 500;
    margin-bottom: 4px;
    font-size: 0.9rem;
}
.form-hint {
    display: block;
    font-size: 0.8rem;
    color: var(--color-text-light);
    margin-top: 4px;
}
.form-row {
    display: flex;
    gap: 16px;
}
.form-row .form-group { flex: 1; }
.input-prefix-group {
    display: flex;
    align-items: stretch;
}
.input-prefix {
    display: flex;
    align-items: center;
    padding: 0 10px;
    background: var(--color-bg-light);
    border: 1px solid var(--color-border);
    border-right: none;
    border-radius: var(--radius) 0 0 var(--radius);
    color: var(--color-text-light);
    font-weight: 500;
}
.input-prefix-group .form-input {
    border-radius: 0 var(--radius) var(--radius) 0;
}
.settings-info-row {
    display: flex;
    justify-content: space-between;
    padding: 10px 0;
    border-bottom: 1px solid var(--color-bg-light);
    font-size: 0.9rem;
}
.settings-info-row:last-child { border-bottom: none; }
.settings-info-label {
    color: var(--color-text-light);
    font-weight: 500;
}

@media (max-width: 640px) {
    .form-row { flex-direction: column; gap: 0; }
}

@media (max-width: 640px) {
    .sub-rating-label { min-width: 100px; font-size: 0.8rem; }
    .score-btn { width: 28px; height: 28px; font-size: 0.75rem; }
}

/* ---------------------------------------------------------------------------
   User Profile
   --------------------------------------------------------------------------- */
/* Profile header is a 2-col grid. Mobile (default): row 1 holds the
   avatar (col 1) + identity meta (col 2); socials, bio, and the action
   button drop below and span both cols so they fill the card width.
   Desktop (≥769px): the avatar stays pinned to col 1 spanning every
   row, and everything else stacks down col 2 — the original side-by-
   side look that had plenty of room. */
.profile-header {
    display: grid;
    grid-template-columns: 80px 1fr;
    column-gap: 16px;
    row-gap: 14px;
    margin: 8px 0 16px;
    padding: 18px 20px;
    background: var(--color-white);
    border-radius: var(--radius-lg);
    border-top: 4px solid var(--color-primary);
    box-shadow: var(--shadow);
}
.profile-header-meta {
    min-width: 0;
    align-self: center;
}
.profile-header > .profile-social-row,
.profile-header > .profile-bio,
.profile-header > .profile-header-action {
    grid-column: 1 / -1;
}
@media (min-width: 769px) {
    .profile-header {
        column-gap: 20px;
    }
    .profile-header > .profile-avatar-lg {
        grid-row: 1 / -1;
        align-self: start;
    }
    .profile-header-meta {
        align-self: start;
    }
    .profile-header > .profile-social-row,
    .profile-header > .profile-bio,
    .profile-header > .profile-header-action {
        grid-column: 2;
    }
}
.profile-avatar-lg {
    width: 80px;
    height: 80px;
    border-radius: 50%;
    background: var(--color-primary);
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    overflow: hidden;
}
.profile-avatar-lg img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.profile-avatar-initial {
    font-size: 2rem;
    font-weight: 700;
    color: var(--color-white);
}
.profile-header-meta h1 {
    font-size: 1.5rem;
    margin-bottom: 2px;
}
.profile-username {
    font-size: 0.9rem;
    color: var(--color-text-light);
    margin-bottom: 4px;
}
.profile-location {
    font-size: 0.85rem;
    color: var(--color-text-light);
    margin-bottom: 2px;
}
.profile-member-since {
    font-size: 0.8rem;
    color: var(--color-text-light);
    margin-bottom: 0;
}
.profile-bio {
    font-size: 0.95rem;
    line-height: 1.5;
    color: var(--color-text);
    margin: 0;
}

/* Profile "where else to find me" social row (#79).
   Brand-colored 44px pill icons directly under the meta lines, above
   the bio. Each link opens in a new tab. Brand colors as the resting
   state draw the eye; hover lifts + adds a soft shadow.

   Touch target: 44x44px hits the standard mobile minimum. */
.profile-social-row {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}
.profile-social-row li { margin: 0; }
.profile-social-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: 999px;
    color: var(--color-white);
    text-decoration: none;
    line-height: 1;
    transition: transform 0.15s ease, box-shadow 0.15s ease, filter 0.15s ease;
    will-change: transform;
}
.profile-social-link svg {
    width: 22px;
    height: 22px;
    display: block;
}
.profile-social-link:hover {
    transform: translateY(-2px) scale(1.05);
    box-shadow: 0 4px 12px rgba(13, 43, 82, 0.18);
    filter: brightness(1.08);
    color: var(--color-white);
}
.profile-social-link:active { transform: translateY(0) scale(1); }

/* Brand color treatments — accurate to each platform's identity. */
.profile-social-website   { background: var(--color-header); }
.profile-social-podcast   { background: #7C3AED; } /* purple — podcast/audio convention */
.profile-social-instagram {
    /* Real Instagram brand uses a gradient. */
    background: radial-gradient(circle at 30% 110%, #fdf497 0%, #fdf497 5%, #fd5949 45%, #d6249f 60%, #285AEB 90%);
}
.profile-social-tiktok    { background: #010101; }
.profile-social-youtube   { background: #FF0000; }
.profile-social-threads   { background: #000000; }
.profile-social-twitter   { background: #000000; }
.profile-social-facebook  { background: #1877F2; }

.visually-hidden {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0);
    white-space: nowrap; border: 0;
}
/* Settings page "Where else to find me" subsection heading. Lighter
   than an <h2> since it sits inside the profile form, but heavier than
   the form-group labels. */
.settings-subsection {
    font-size: 1rem;
    font-weight: 600;
    color: var(--color-header);
    margin: 24px 0 4px;
    padding-top: 16px;
    border-top: 1px solid var(--color-border);
}
.settings-subsection-hint {
    margin: 0 0 12px;
    color: var(--color-text-light);
}

.profile-stats {
    display: flex;
    gap: 32px;
    justify-content: space-around;
    margin-bottom: 16px;
    padding: 16px 20px;
    background: var(--color-white);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
}
.profile-stat {
    text-align: center;
}
.profile-stat-number {
    display: block;
    font-size: 1.5rem;
    font-weight: 700;
    color: var(--color-primary);
    line-height: 1.2;
}
.profile-stat-label {
    font-size: 0.8rem;
    color: var(--color-text-light);
}

/* #80 Phase 3: visibility checkboxes on settings form */
.settings-visibility-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px 24px;
}
@media (max-width: 600px) {
    .settings-visibility-grid { grid-template-columns: 1fr; }
}
.settings-visibility-row {
    display: flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
    font-weight: 500;
}
.settings-visibility-row input[type="checkbox"] {
    margin: 0;
    width: 18px;
    height: 18px;
}
.settings-visibility-grid > .form-hint {
    grid-column: 1 / -1;
    color: var(--color-text-light);
    margin-top: 4px;
}

/* #80 Phase 2: minimal-stub view for private / followers-only profiles */
.profile-private-stub {
    background: var(--color-white);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    padding: 32px 24px;
    margin-bottom: 16px;
    text-align: center;
    color: var(--color-text-light);
}
.profile-private-stub p {
    margin: 0;
    font-size: 0.95rem;
}

/* #80 Phase 1: photos tab on profile */
.profile-photo-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 16px;
}
@media (max-width: 768px) {
    .profile-photo-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.profile-photo-tile {
    background: var(--color-white);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    overflow: hidden;
    display: flex;
    flex-direction: column;
}
.profile-photo-tile.is-pending {
    opacity: 0.85;
}
.profile-photo-thumb {
    position: relative;
    display: block;
    aspect-ratio: 1 / 1;
    background: var(--color-bg);
}
.profile-photo-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.profile-photo-pending-badge {
    position: absolute;
    top: 8px;
    left: 8px;
    background: rgba(13, 43, 82, 0.85);
    color: var(--color-white);
    font-size: 0.7rem;
    font-weight: 700;
    padding: 3px 8px;
    border-radius: var(--radius);
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.profile-photo-meta {
    padding: 8px 10px;
    flex: 1;
}
.profile-photo-subject {
    font-size: 0.88rem;
    font-weight: 600;
    color: var(--color-header);
    text-decoration: none;
    display: block;
}
.profile-photo-subject:hover {
    color: var(--color-primary);
}
.profile-photo-caption {
    margin: 4px 0 0;
    font-size: 0.8rem;
    color: var(--color-text-light);
    line-height: 1.3;
}
.profile-photo-actions {
    display: flex;
    gap: 6px;
    padding: 0 10px 10px;
}
.profile-photo-action {
    background: transparent;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 3px 8px;
    cursor: pointer;
    font-size: 0.72rem;
    color: var(--color-text-light);
}
.profile-photo-action:hover {
    border-color: var(--color-primary);
    color: var(--color-primary);
}
.profile-photo-action.profile-photo-delete:hover {
    border-color: var(--color-error);
    color: var(--color-error);
}

.review-context {
    display: flex;
    flex-direction: column;
    gap: 2px;
}
.review-target {
    font-weight: 600;
    font-size: 0.95rem;
}
.review-target-sub {
    font-size: 0.8rem;
    color: var(--color-text-light);
}
.review-target-sub a {
    color: var(--color-text-light);
}
.review-target-sub a:hover {
    color: var(--color-primary);
}

/* ===========================================================================
   Mobile usability pass — narrow-screen overrides for ≤480px (phones)
   Surveyed via `templates/*.html` + this stylesheet; targets the BLOCKING
   and HIGH-severity issues. Lighter overrides at the 600px breakpoint are
   inline at their respective sections (see review form ≈ line 2820, etc.).
   =========================================================================== */
@media (max-width: 480px) {
    /* Restaurant info table: shrink label column so values aren't squeezed. */
    .info-table td:first-child {
        width: 80px;
        font-size: 0.85rem;
    }
    .info-table td {
        font-size: 0.85rem;
    }

    /* Search filters: full-width stack instead of a cramped 4-up row. */
    .filter-select {
        width: 100%;
    }

    /* Venue grid was 2-col on phones — cards became unreadable. Single
       column under 480px. */
    .venue-grid {
        grid-template-columns: 1fr;
    }

    /* Sub-rating bars on restaurant/menu-item pages — shorter labels
       so the bar gets useful width on narrow viewports. */
    .sub-rating-label {
        min-width: 80px;
        font-size: 0.8rem;
    }

    /* Multi-menu restaurants: stack the meal-period toggle buttons
       instead of letting them overflow horizontally. */
    .menu-toggle-bar {
        flex-direction: column;
    }
    .menu-toggle-btn {
        width: 100%;
    }

    /* Profile stats: 4 stat tiles with 32px gaps was cramped.
       Tighter gap + slightly smaller numbers fits 4-across. */
    .profile-stats {
        gap: 12px;
    }
    .profile-stat-number {
        font-size: 1.5rem;
    }

    /* List picker popover: never wider than the screen on small phones. */
    .list-picker-popover {
        max-width: 90vw;
    }
}

/* Source attribution footnote on restaurant + menu-item detail pages
   (#90.14 — GEO citation-quality signal). Muted so it reads as a
   data-provenance footer rather than competing with content. */
.data-attribution {
    margin: 20px 0 0;
    padding: 12px 16px;
    background: var(--color-bg);
    border-radius: var(--radius);
    font-size: 0.78rem;
    line-height: 1.5;
    color: var(--color-text-light);
    border-left: 3px solid var(--color-primary);
}

/* ---------------------------------------------------------------------------
   Blog index (#85)
   Featured row at top (up to 2 pinned articles), then a 2-col layout:
   main chronological feed + sidebar (Topics + Recent Posts). Sidebar
   stacks below the main feed on mobile.
   --------------------------------------------------------------------------- */

.blog-index {
    /* container styles are inherited from .content-container */
}

.blog-topic-indicator {
    background: var(--color-white);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    padding: 10px 14px;
    margin: 8px 0 16px;
    font-size: 0.9rem;
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}
.blog-topic-chip {
    display: inline-block;
    background: var(--color-primary);
    color: var(--color-white);
    border-radius: 999px;
    padding: 2px 10px;
    font-weight: 600;
}
.blog-topic-clear {
    margin-left: auto;
    font-size: 0.85rem;
}

/* --- Featured row --- */
.blog-featured {
    margin: 8px 0 24px;
}
.blog-featured-row {
    display: grid;
    /* 2-up at every viewport. Mobile-stacked featured cards were too
       image-heavy and pushed the main feed off-screen — the pinned
       row reads as a compact "what's hot" duo regardless of width. */
    grid-template-columns: 1fr 1fr;
    gap: 12px;
}
@media (min-width: 769px) {
    .blog-featured-row {
        gap: 16px;
    }
}
.blog-featured-card {
    display: flex;
    flex-direction: column;
    background: var(--color-white);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    overflow: hidden;
    text-decoration: none;
    color: inherit;
    border-top: 4px solid var(--color-primary);
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.blog-featured-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
}
.blog-featured-card-image {
    aspect-ratio: 16 / 9;
    overflow: hidden;
    background: var(--color-bg);
}
.blog-featured-card-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Placeholder shown when an article has no hero image. Branded
   gradient with the eyebrow (or first letter of the title) so every
   card has visual weight — and articles still feel distinct without
   editors needing to upload a hero for each post. */
.blog-card-placeholder {
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 12px;
    background: linear-gradient(135deg, var(--color-primary) 0%, color-mix(in srgb, var(--color-primary) 70%, #000 30%) 100%);
    color: var(--color-white);
    text-align: center;
}
.blog-card-placeholder-text {
    font-size: 1.15rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    line-height: 1.2;
    /* Cap visual size so a long eyebrow doesn't overwhelm the card. */
    max-width: 80%;
}
.blog-featured-card-body {
    padding: 16px 18px 18px;
}
.blog-featured-badge {
    display: inline-block;
    background: var(--color-primary);
    color: var(--color-white);
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    padding: 2px 8px;
    border-radius: var(--radius);
    margin-bottom: 8px;
}
.blog-featured-card-title {
    font-size: 1.25rem;
    line-height: 1.3;
    margin: 4px 0 8px;
}
.blog-featured-card-blurb {
    color: var(--color-text-light);
    font-size: 0.95rem;
    margin: 0 0 10px;
    line-height: 1.5;
}

/* --- 2-col main + sidebar layout --- */
.blog-layout {
    display: grid;
    grid-template-columns: 1fr;
    gap: 20px;
}
@media (min-width: 901px) {
    .blog-layout {
        grid-template-columns: minmax(0, 1fr) 280px;
    }
}

/* --- Main feed (list-style cards: image left, text right) --- */
.blog-main {
    min-width: 0;
}
.blog-empty {
    background: var(--color-white);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    padding: 28px 20px;
    text-align: center;
}
.blog-empty p {
    margin-bottom: 10px;
}
.blog-list-card {
    display: flex;
    background: var(--color-white);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    overflow: hidden;
    text-decoration: none;
    color: inherit;
    margin-bottom: 14px;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.blog-list-card:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.12);
}
.blog-list-card-image {
    flex-shrink: 0;
    width: 180px;
    background: var(--color-bg);
    overflow: hidden;
}
.blog-list-card-image img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}
.blog-list-card-body {
    padding: 14px 18px 14px 16px;
    min-width: 0;
    flex: 1;
}
.blog-list-card-title {
    font-size: 1.1rem;
    line-height: 1.3;
    margin: 4px 0 6px;
}
.blog-list-card-blurb {
    color: var(--color-text-light);
    font-size: 0.9rem;
    margin: 0 0 6px;
    line-height: 1.45;
}
.blog-card-eyebrow {
    color: var(--color-primary);
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin: 0;
}
.blog-card-meta {
    color: var(--color-text-light);
    font-size: 0.8rem;
    margin: 0;
}

@media (max-width: 600px) {
    /* Compact mobile sizing — image-left layout preserved so 2-4
       cards fit per screen instead of 1-2 from a stacked layout.
       Everything tighter: narrower image, smaller type, less padding,
       tighter inter-card gap. Blurb clamped to 2 lines so cards stay
       a consistent height down the feed. */
    .blog-list-card {
        margin-bottom: 10px;
    }
    .blog-list-card-image {
        width: 110px;
    }
    .blog-list-card-body {
        padding: 10px 12px 10px 12px;
    }
    .blog-list-card-title {
        font-size: 1rem;
        line-height: 1.25;
        margin: 2px 0 4px;
    }
    .blog-list-card-blurb {
        font-size: 0.82rem;
        line-height: 1.4;
        margin: 0 0 4px;
        /* 2-line clamp keeps card heights consistent down the feed. */
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
    }
    .blog-card-eyebrow {
        font-size: 0.65rem;
    }
    .blog-card-meta {
        font-size: 0.7rem;
    }

    /* Featured cards stay 2-up but shrink their type so the body is
       readable in the narrower slots. Blurb hidden — at this width
       title + meta carry the card cleanly. */
    .blog-featured-card-body {
        padding: 10px 12px 12px;
    }
    .blog-featured-card-title {
        font-size: 0.95rem;
        line-height: 1.25;
        margin: 4px 0 4px;
    }
    .blog-featured-card-blurb {
        display: none;
    }
    .blog-featured-badge {
        font-size: 0.6rem;
        padding: 1px 6px;
        margin-bottom: 4px;
    }
    .blog-card-placeholder-text {
        font-size: 0.85rem;
        letter-spacing: 0.06em;
    }
}

@media (max-width: 768px) {
    /* Hide the sidebar on phones. Recent Posts duplicates the main
       feed at this width, and Topics is reachable from the eyebrow
       labels on each card. Related-post suggestions belong at the
       bottom of individual article pages (see follow-up). */
    .blog-sidebar {
        display: none;
    }
}

/* --- Sidebar (Topics + Recent Posts) --- */
.blog-sidebar {
    display: flex;
    flex-direction: column;
    gap: 14px;
    min-width: 0;
}
.blog-sidebar-card {
    background: var(--color-white);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow);
    padding: 14px 16px 16px;
}
.blog-sidebar-heading {
    font-size: 0.9rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--color-text-light);
    margin: 0 0 10px;
}

.blog-topic-list,
.blog-recent-list {
    list-style: none;
    margin: 0;
    padding: 0;
}
.blog-topic-list li,
.blog-recent-list li {
    margin: 0;
    border-top: 1px solid rgba(0, 0, 0, 0.06);
}
.blog-topic-list li:first-child,
.blog-recent-list li:first-child {
    border-top: none;
}

.blog-topic-link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 0;
    text-decoration: none;
    color: var(--color-text);
    font-size: 0.92rem;
}
.blog-topic-link:hover {
    color: var(--color-primary);
}
.blog-topic-link.is-active {
    color: var(--color-primary);
    font-weight: 600;
}
.blog-topic-link-count {
    color: var(--color-text-light);
    font-size: 0.8rem;
    background: var(--color-bg);
    padding: 1px 8px;
    border-radius: 999px;
}

.blog-recent-link {
    display: flex;
    flex-direction: column;
    padding: 8px 0;
    text-decoration: none;
    color: var(--color-text);
}
.blog-recent-link-title {
    font-size: 0.92rem;
    line-height: 1.3;
}
.blog-recent-link:hover .blog-recent-link-title {
    color: var(--color-primary);
}
.blog-recent-link-date {
    color: var(--color-text-light);
    font-size: 0.75rem;
    margin-top: 2px;
}

/* ============================================================
   Restaurant detail page — #106 redesign
   ------------------------------------------------------------
   Header / carousel / popular items / reviews / guest photos /
   related. Star scale 0-5 via half-step rendering. Uses semantic
   class names (no rmu-* prefix). Obsolete styles for the prior
   layout (.restaurant-summary, .mousedining-cta, .menu-shortcuts,
   .item-carousel-compact, .review-aggregate-row) are scheduled for
   cleanup but stay in place until this design ships.
   ============================================================ */

/* === Stars (shared, used by header + review cards) =====================
   Chunky rounded-point star — friendlier than the pointy classic
   polygon, warmer gold (#FFAB40) so the rating reads as celebratory
   rather than utility. Default size bumped to 20px; per-context
   overrides via --star-size still work. (#136) */
.stars {
    display: inline-flex;
    gap: 0;
    vertical-align: middle;
}
/* SVG star paths have ~2 units of viewBox padding on each side, so
   adjacent stars look gappier than the flex gap suggests. A small
   negative margin absorbs that whitespace and reads as a tight
   star strip. (#136) */
.stars > .star + .star {
    margin-left: -2px;
}
.star {
    width: var(--star-size, 20px);
    height: var(--star-size, 20px);
    -webkit-mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 2c.41 0 .78.25.93.63l2.21 4.91 5.36.78c.85.13 1.19 1.18.58 1.78l-3.88 3.78.91 5.34c.14.84-.75 1.49-1.51 1.09L12 17.78l-4.79 2.52c-.76.4-1.65-.25-1.51-1.09l.91-5.34-3.88-3.78c-.61-.6-.27-1.65.58-1.78l5.36-.78 2.21-4.91A1.013 1.013 0 0 1 12 2z'/></svg>");
    mask-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 2c.41 0 .78.25.93.63l2.21 4.91 5.36.78c.85.13 1.19 1.18.58 1.78l-3.88 3.78.91 5.34c.14.84-.75 1.49-1.51 1.09L12 17.78l-4.79 2.52c-.76.4-1.65-.25-1.51-1.09l.91-5.34-3.88-3.78c-.61-.6-.27-1.65.58-1.78l5.36-.78 2.21-4.91A1.013 1.013 0 0 1 12 2z'/></svg>");
    -webkit-mask-size: contain;
    mask-size: contain;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    background: #e1e1e1;
}
.star-full { background: #FFAB40; }
.star-half { background: linear-gradient(90deg, #FFAB40 50%, #e1e1e1 50%); }

/* === btn-external utility ============================================== */
/* Transparent navy outline button — used on CTAs that leave TPF
   (partner links, off-site references). Distinguishes external from
   internal filled .btn-primary CTAs. */
.btn-external {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    white-space: nowrap;
    background: transparent;
    border: 1.5px solid var(--color-header);
    color: var(--color-header);
    transition: background 0.12s, color 0.12s;
}
.btn-external:hover {
    background: var(--color-header);
    color: var(--color-white);
    border-color: var(--color-header);
}
.btn-external svg {
    flex-shrink: 0;
}

/* Coral outline button — internal link variant. Same shape as
   .btn-external, no arrow icon. Brandon 2026-06-19: external
   links wear the navy + arrow chrome so guests can spot off-site
   destinations; internal navigation gets the coral equivalent. */
.btn-internal {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    white-space: nowrap;
    background: transparent;
    border: 1.5px solid var(--color-primary);
    color: var(--color-primary);
    transition: background 0.12s, color 0.12s;
}
.btn-internal:hover {
    background: var(--color-primary);
    color: var(--color-white);
    border-color: var(--color-primary);
}

/* === Detail-page header (restaurant + menu item) ======================
   See the heading-pattern comment near .page-heading-card for the
   intentional split between this primitive and .page-heading-card. */
.detail-header {
    background: var(--color-white);
    border: var(--card-border);
    border-radius: var(--radius-card);
    /* Salmon top accent matching .page-heading-card so heading-card
       chrome reads as one consistent primitive across listing AND
       detail pages (Brandon 2026-06-21). */
    border-top: 4px solid var(--color-primary);
    margin: 8px 0 16px;
    overflow: hidden;
}
.detail-header-content {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: 24px;
    padding: 20px;
    align-items: start;
}
.detail-header-left { min-width: 0; }
.detail-header-right {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 10px;
}
.restaurant-name-row {
    display: flex;
    align-items: center;
    gap: 12px;
}
.restaurant-name {
    margin: 0;
    font-size: 1.6rem;
    font-weight: 800;
    color: var(--color-header);
    line-height: 1.15;
}
.restaurant-name-bookmark {
    flex-shrink: 0;
}
/* Anonymous variant — same shape as the logged-in bookmark, with
   a muted tint so the call-to-action reads as "you could save this"
   rather than "you have saved this". Click opens the sign-up popup
   (Brandon 2026-06-21). */
.restaurant-name-bookmark-anon {
    opacity: 0.6;
}
.restaurant-name-bookmark-anon:hover {
    opacity: 1;
}
/* "Report a correction" flag button — neutral grey, same shape as the
   bookmark, sits next to it in the header chrome (#208 Phase A). */
.restaurant-name-report {
    flex-shrink: 0;
    color: var(--color-text-light);
    background: transparent;
    border: 1px solid var(--color-border);
}
.restaurant-name-report:hover {
    color: var(--color-text);
    background: var(--color-bg);
}
/* Admin Quick Edit pencil — same shape as the report flag but
   tinted with the primary color so it reads as "admin action"
   (#208 Phase B). Only rendered when isAdminEditMode(). */
.restaurant-name-admin-edit {
    color: var(--color-primary) !important;
    border-color: var(--color-primary) !important;
}
.restaurant-name-admin-edit:hover {
    background: var(--color-primary-tint, #ffe5e0) !important;
}

/* Admin mode bar — small fixed-bottom strip on every page when
   the viewer has admin access. Lets editors toggle between admin
   chrome (default) and view-as-user preview without losing their
   session. (#208 Phase B) */
.admin-mode-bar {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 30;
    background: var(--color-header);
    color: var(--color-white);
    padding: 6px 12px;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 12px;
    font-size: 0.82rem;
    box-shadow: 0 -2px 6px rgba(0, 0, 0, 0.08);
}
.admin-mode-bar-label {
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
}
.admin-mode-bar-label-muted {
    color: rgba(255, 255, 255, 0.6);
}
.admin-mode-bar-toggle {
    background: transparent;
    border: 1px solid rgba(255, 255, 255, 0.4);
    color: var(--color-white);
    padding: 3px 10px;
    border-radius: var(--radius);
    font-size: 0.78rem;
    cursor: pointer;
}
.admin-mode-bar-toggle:hover {
    background: rgba(255, 255, 255, 0.1);
}
/* Push the page content above the bar so the bar doesn't overlap
   the footer attribution / floating buttons. */
body:has(.admin-mode-bar) {
    padding-bottom: 36px;
}
.restaurant-location {
    color: var(--color-text-light);
    font-size: 0.92rem;
    margin: 4px 0 8px;
}
.restaurant-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}
.restaurant-tag {
    padding: 3px 9px;
    background: var(--color-bg);
    border-radius: var(--radius-card);
    font-size: 0.78rem;
    color: var(--color-text);
    text-decoration: none;
}
.restaurant-tag:hover {
    background: var(--color-bg-light);
    color: var(--color-primary);
}
/* Price tag mirrors .badge-price (green pill) so the $/$$/$$$ symbol
   reads the same across the site regardless of which tag system the
   surface uses. */
.restaurant-tag-price {
    background: #E8F5E9;
    color: #2E7D32;
    font-weight: 700;
}
.restaurant-rating-row {
    display: flex;
    align-items: center;
    gap: 10px;
}
.restaurant-rating-num {
    font-size: 1.5rem;
    font-weight: 800;
    color: var(--color-header);
    line-height: 1;
}
.restaurant-rating-count {
    color: var(--color-text-light);
    font-size: 0.85rem;
    padding-left: 4px;
    border-left: 1px solid var(--color-border);
}
/* Park-rank trust badge — sits between the rating row and the
   action buttons. Soft beige pill links into /search filtered to
   the park so the comparison is one tap away (#199). */
.restaurant-park-rank {
    display: inline-flex;
    align-items: center;
    padding: 4px 10px;
    background: #fff8e1;
    color: #8a6d1d;
    font-size: 0.82rem;
    font-weight: 600;
    border-radius: 999px;
    text-decoration: none;
    transition: background 0.12s, color 0.12s;
}
.restaurant-park-rank:hover {
    background: #ffecb3;
    color: #6d5100;
}

/* Header action row — View Menu + Check Availability side-by-
   side. Sits below the rating in the right column on desktop;
   stretches full-width below the header content on mobile (see
   the @media block below). Brandon 2026-06-19. */
.restaurant-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-top: 10px;
}

/* === Section 2: Photo carousel (Option D) ============================== */
.restaurant-carousel-card {
    background: var(--color-white);
    border: var(--card-border);
    border-radius: var(--radius-card);
    margin-bottom: 16px;
    overflow: hidden;
    padding: 0;
}
.restaurant-carousel {
    display: grid;
    grid-template-columns: 2fr 1fr 1fr;
    grid-template-rows: 1fr 1fr;
    gap: 4px;
    aspect-ratio: 16/4;
    background: var(--color-bg);
}
.restaurant-carousel-slide {
    position: relative;
    background-size: cover;
    background-position: center;
}
.restaurant-carousel-slide:nth-child(1) {
    grid-row: 1 / span 2;
}
.restaurant-carousel-attribution {
    position: absolute;
    bottom: 6px;
    right: 6px;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 8px;
    background: rgba(0, 0, 0, 0.55);
    color: var(--color-white);
    border-radius: var(--radius-lg);
    font-size: 0.7rem;
    font-weight: 600;
    line-height: 1;
    text-decoration: none;
}
.restaurant-carousel-attribution:hover {
    background: rgba(0, 0, 0, 0.75);
    color: var(--color-white);
}
/* Share-a-photo tile fills empty cells when image count < 4. Dashed
   border signals "drop content here"; hover state shifts to primary. */
.restaurant-carousel-share {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    background: var(--color-bg);
    border: 2px dashed var(--color-border);
    color: var(--color-text-light);
    font-size: 0.85rem;
    font-weight: 600;
    text-align: center;
    text-decoration: none;
    padding: 12px;
    transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.restaurant-carousel-share:hover {
    background: var(--color-bg-light);
    border-color: var(--color-primary);
    color: var(--color-primary);
}
.restaurant-carousel-share svg { flex-shrink: 0; }
.restaurant-carousel[data-image-count="0"] .restaurant-carousel-share {
    grid-column: 1 / -1;
    grid-row: 1 / -1;
}
.restaurant-carousel[data-image-count="1"] .restaurant-carousel-share {
    grid-column: 2 / span 2;
    grid-row: 1 / span 2;
}
.restaurant-carousel[data-image-count="2"] .restaurant-carousel-slide:nth-child(2) {
    grid-column: 2;
    grid-row: 1 / span 2;
}
.restaurant-carousel[data-image-count="2"] .restaurant-carousel-share {
    grid-column: 3;
    grid-row: 1 / span 2;
}
.restaurant-carousel[data-image-count="3"] .restaurant-carousel-share {
    grid-column: 2 / span 2;
    grid-row: 2;
}

/* === Shared section chrome (header.html + popular + reviews + photos) === */
/* Override the older .restaurant-section rule's top border treatment.
   The new design uses white card containers with no inter-section
   border line. */
.restaurant-section {
    background: var(--color-white);
    border: var(--card-border);
    border-radius: var(--radius-card);
    padding: 16px 18px 18px;
    margin: 0 0 16px;
    border-top: 1px solid var(--color-border);
}
.restaurant-section-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 12px;
}
.restaurant-section-title {
    margin: 0;
    font-size: 1.2rem;
    color: var(--color-header);
}
.restaurant-section > h2:not(.restaurant-section-title) {
    margin: 0 0 12px;
}

/* === Section 3: Popular Items ========================================== */
.popular-items-row {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 12px;
}
.popular-item-card {
    display: block;
    text-decoration: none;
    color: var(--color-text);
}
.popular-item-card:hover {
    text-decoration: none;
}
.popular-item-thumb {
    position: relative;
    width: 100%;
    aspect-ratio: 1/1;
    border-radius: var(--radius-card);
    background-size: cover;
    background-position: center;
    overflow: hidden;
}
/* hsl-letter placeholder. Background hue set inline (crc32 hash
   of the name). Brandon prefers this over a neutral camera SVG. */
.popular-item-thumb-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
}
.popular-item-thumb-letter {
    color: rgba(255, 255, 255, 0.92);
    font-size: 1.6rem;
    font-weight: 700;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
    line-height: 1;
}
/* Camera-SVG placeholder — replaces the colored-letter pattern for
   parity with /search + homepage tiles (#153 item 1). Same fill/drop-
   shadow treatment as .entity-tile-thumb-camera. */
.popular-item-thumb-camera {
    width: 28px;
    height: 28px;
    color: rgba(255, 255, 255, 0.92);
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.15));
}
/* Title block locked to exactly 2 lines tall — short names get
   padded with empty space, long names truncate via the line-clamp.
   This keeps the .popular-item-footer (menu name + % pill) sitting
   on the same horizontal plane across every card in the row,
   regardless of name length. (Brandon 2026-06-19) */
.popular-item-name {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: 0.85rem;
    font-weight: 600;
    line-height: 1.2;
    margin-top: 6px;
    height: 2.4em;
}
/* Lightbox modal — enlarges any photo when clicked, swipes/
   arrow-keys to navigate the rest of the gallery. Single instance
   appended to the page by the lightbox JS; triggers carry
   data-lightbox-group + data-lightbox-url + data-lightbox-credit
   attributes. */
.lightbox-overlay {
    position: fixed;
    inset: 0;
    z-index: 1000;
    background: rgba(0, 0, 0, 0.85);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
}
.lightbox-overlay[hidden] {
    display: none;
}
.lightbox-stage {
    position: relative;
    max-width: 100%;
    max-height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}
.lightbox-image {
    max-width: 100%;
    max-height: 90vh;
    display: block;
    box-shadow: 0 8px 32px rgba(0, 0, 0, 0.35);
    border-radius: var(--radius);
}
.lightbox-close {
    position: absolute;
    top: -42px;
    right: -8px;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    border: 0;
    background: rgba(255, 255, 255, 0.92);
    color: var(--color-header);
    font-size: 1.25rem;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.lightbox-prev,
.lightbox-next {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    width: 44px;
    height: 44px;
    border-radius: 50%;
    border: 0;
    background: rgba(255, 255, 255, 0.92);
    color: var(--color-header);
    font-size: 1.4rem;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.lightbox-prev { left: -56px; }
.lightbox-next { right: -56px; }
.lightbox-prev[disabled],
.lightbox-next[disabled] {
    opacity: 0.4;
    cursor: not-allowed;
}
/* On narrow viewports the arrows tuck inside the image edges. */
@media (max-width: 768px) {
    .lightbox-overlay { padding: 12px; }
    .lightbox-close { top: -38px; right: 0; }
    .lightbox-prev { left: 6px; background: rgba(255, 255, 255, 0.85); }
    .lightbox-next { right: 6px; background: rgba(255, 255, 255, 0.85); }
}
/* Credit chip on the lightbox image — bottom-right corner,
   same shape as .image-attribution. The JS injects the HTML
   directly into .lightbox-credit. */
.lightbox-credit {
    position: absolute;
    bottom: 8px;
    right: 8px;
}
.lightbox-credit:empty { display: none; }
/* Caption sits below the image on a dark translucent strip so it
   reads cleanly against any background photo (Brandon 2026-06-20).
   Auto-hidden when empty via the JS toggle in lightbox.js. */
.lightbox-caption {
    margin: 10px 0 0;
    padding: 8px 14px;
    background: rgba(0, 0, 0, 0.6);
    color: #fff;
    font-size: 0.95rem;
    line-height: 1.4;
    border-radius: var(--radius);
    max-width: 80vw;
    text-align: center;
}

/* Footer row — menu name on the left, % rating pill on the right.
   Better use of card width than stacking the two below the name
   (Brandon 2026-06-19). */
.popular-item-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-top: 4px;
    min-height: 24px;
}
.popular-item-meta {
    flex: 1 1 auto;
    min-width: 0;
    font-size: 0.75rem;
    color: var(--color-text-light);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.popular-item-rating {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
}
.popular-items-footer {
    margin-top: 20px;
    display: flex;
    justify-content: center;
}

/* === Section 4: Reviews ================================================ */
/* Review form section gets a subtle inset bg so it's visually
   distinct from the review list below. */
.review-form-section,
.photo-upload-section {
    position: relative;
}
.review-form-section {
    margin: 0 0 16px;
    padding: 16px 40px 16px 16px;
    background: var(--color-bg);
    border-radius: var(--radius-card);
}
/* Close X in the upper-right of an expandable form panel makes the
   toggle relationship obvious — tapping the section-head button
   again to collapse wasn't intuitive (Brandon 2026-06-20). */
.form-section-close {
    position: absolute;
    top: 8px;
    right: 8px;
    width: 32px;
    height: 32px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border: none;
    background: transparent;
    color: var(--color-text-light);
    font-size: 1.6rem;
    line-height: 1;
    cursor: pointer;
    border-radius: 50%;
    transition: background 0.15s, color 0.15s;
}
.form-section-close:hover {
    background: rgba(0, 0, 0, 0.06);
    color: var(--color-text);
}
/* Chip picker — capped-multi-select with tone bands. */
.review-chip-picker {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 4px;
}
.review-chip-pick {
    padding: 5px 12px;
    background: var(--color-white);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-lg);
    color: var(--color-text);
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
    transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.review-chip-pick:hover {
    border-color: var(--color-primary);
    color: var(--color-primary);
}
.review-chip-pick.is-selected.review-chip-tone-positive {
    background: #C8E6C9;
    border-color: #81C784;
    color: #1B5E20;
}
.review-chip-pick.is-selected.review-chip-tone-negative {
    background: #FFCDD2;
    border-color: #E57373;
    color: #B71C1C;
}
.review-chip-pick.is-selected.review-chip-tone-neutral {
    background: var(--color-bg);
    border-color: var(--color-border);
    color: var(--color-text);
}
/* Review list — redefined (the old flat list becomes a vertical stack
   of bordered cards). */
.review-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.review-card {
    background: var(--color-bg);
    border-radius: var(--radius-card);
    padding: 14px 16px;
}
.review-card.review-pending {
    border-left: 3px solid var(--color-warning, #d97706);
}
.review-pending-badge {
    display: inline-block;
    margin-bottom: 6px;
    padding: 2px 8px;
    background: var(--color-warning-bg, #fef3c7);
    color: var(--color-warning, #d97706);
    border-radius: var(--radius);
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.review-head {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 12px;
    margin-bottom: 8px;
}
.review-author {
    display: flex;
    gap: 10px;
    align-items: center;
    min-width: 0;
}
.review-avatar {
    width: 36px;
    height: 36px;
    flex-shrink: 0;
    background: var(--color-primary);
    color: var(--color-white);
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    font-weight: 700;
}
.review-author-text {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    min-width: 0;
}
.review-name {
    font-weight: 700;
    color: var(--color-header);
    font-size: 0.95rem;
    text-decoration: none;
}
.review-name:hover {
    color: var(--color-primary);
}
.review-verified-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    flex-shrink: 0;
    background: #1D9BF0;
    color: var(--color-white);
    border-radius: 50%;
    font-size: 0.62rem;
    font-weight: 700;
    line-height: 1;
}
.review-time {
    color: var(--color-text-light);
    font-size: 0.78rem;
}
.review-rating {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex-shrink: 0;
}
.review-rating-num {
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--color-header);
}
.review-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    margin-top: 8px;
}
.review-chip {
    padding: 3px 11px;
    border-radius: var(--radius-lg);
    border: 1px solid transparent;
    font-size: 0.74rem;
    font-weight: 700;
    white-space: nowrap;
}
.review-chip-tone-positive {
    background: #C8E6C9;
    border-color: #81C784;
    color: #1B5E20;
}
.review-chip-tone-negative {
    background: #FFCDD2;
    border-color: #E57373;
    color: #B71C1C;
}
.review-chip-tone-neutral {
    background: var(--color-bg);
    border-color: var(--color-border);
    color: var(--color-text);
}
.review-body {
    margin: 6px 0;
    font-size: 0.92rem;
    line-height: 1.45;
}

/* === Section 6: Related ================================================ */
.restaurant-related-row {
    display: flex;
    gap: 16px;
    flex-wrap: wrap;
}
.restaurant-related-link {
    color: var(--color-primary);
    text-decoration: none;
    font-size: 0.9rem;
    font-weight: 600;
}
.restaurant-related-link:hover {
    color: var(--color-primary-dark);
}

/* === Mobile breakpoints ================================================ */
@media (max-width: 600px) {
    /* Section card spacing tightens on phones so two-column
       section heads (title + action button) don't get pushed
       off-screen by 18px gutters. Also makes the head wrap
       gracefully if the action button label runs long (Brandon
       2026-06-20 — Leave a Review / Share a Photo were getting
       cut off on the menu-item page). */
    .restaurant-section {
        padding: 14px 14px 16px;
    }
    .restaurant-section-head {
        flex-wrap: wrap;
        align-items: center;
        gap: 8px 12px;
    }
    .restaurant-section-title {
        font-size: 1.1rem;
    }
    .restaurant-section-head .btn {
        flex-shrink: 0;
    }
}
@media (max-width: 700px) {
    .detail-header-content {
        grid-template-columns: 1fr;
        gap: 14px;
        padding: 16px 14px;
    }
    .detail-header-right {
        align-items: stretch;
        gap: 10px;
        padding-top: 14px;
        border-top: 1px solid var(--color-border);
        width: 100%;
    }
    .restaurant-rating-row { gap: 8px; }
    .restaurant-rating-row .stars { --star-size: 17px; }
    .restaurant-rating-num { font-size: 1.4rem; }
    /* Unify the mobile padding on both detail-header inner
       containers so the restaurant + menu-item detail pages render
       with the same chrome. Previously restaurant used 16/14 and
       menu-item used 18/20/12 — small mismatches that read as
       inconsistency when switching between pages
       (Brandon 2026-06-24). */
    .detail-header-content,
    .menu-item-header .menu-item-header-body {
        padding: 16px;
    }
    /* Float the bookmark + report-flag buttons in the top-right
       corner of the detail-header card on mobile. Position relative
       to the SHARED outer .detail-header (no padding of its own), so
       the offsets are identical on both pages. Avoids the awkward
       "long name wraps around two small buttons" inline layout. */
    .detail-header {
        position: relative;
    }
    .restaurant-name-row {
        gap: 0;
        padding-right: 72px;
    }
    .restaurant-name-row .btn-list-add {
        position: absolute;
        top: 16px;
        width: 30px;
        height: 30px;
    }
    .restaurant-name-row .btn-list-add svg {
        width: 13px;
        height: 13px;
    }
    .restaurant-name-row .restaurant-name-bookmark        { right: 52px; }
    .restaurant-name-row .restaurant-name-bookmark-anon   { right: 52px; }
    .restaurant-name-row .restaurant-name-report          { right: 16px; }
    .restaurant-rating-count { font-size: 0.78rem; }
    /* Action buttons stretch to share the full header width on
       mobile (View Menu | Check Availability), giving guests two
       big tap targets right under the header content. */
    .restaurant-actions {
        margin-top: 0;
        gap: 10px;
    }
    .restaurant-actions .btn {
        flex: 1 1 0;
    }
    /* Review rating shrinks on mobile so the 18px desktop stars don't
       overflow the card width. */
    .review-rating { gap: 4px; }
    .review-rating-num { font-size: 0.85rem; }
    .review-rating .star {
        width: 13px;
        height: 13px;
    }
}

@media (max-width: 768px) {
    /* Popular Items: 6-up grid becomes horizontal scroll strip — all 6
       visible via swipe rather than clipping to fewer. */
    .popular-items-row {
        display: flex;
        grid-template-columns: none;
        overflow-x: auto;
        gap: 10px;
        padding-bottom: 6px;
        scroll-snap-type: x mandatory;
        scrollbar-width: thin;
    }
    .popular-item-card {
        flex: 0 0 110px;
        scroll-snap-align: start;
    }
    .popular-item-name { font-size: 0.78rem; }
}

@media (max-width: 700px) {
    .restaurant-carousel { aspect-ratio: 16/6; }
    .restaurant-carousel-share {
        font-size: 0.78rem;
        gap: 6px;
        padding: 8px;
    }
    .restaurant-carousel-share svg {
        width: 22px;
        height: 22px;
    }
}

/* Compact restaurant score for listing surfaces (search, homepage,
   park, lists). Number + small stars inline — same visual language
   as the restaurant header just shrunk. Replaces the old colored
   .score-badge for restaurant rows. Use renderStars($score, 12). */
/* Generic numeric-score + stars inline row. Was .restaurant-card-score
   (a misnomer once it spread to review rows + locations cards).
   Renamed for semantic accuracy — #157. */
.score-inline {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 0.85rem;
    line-height: 1;
    color: var(--color-header);
}
.score-inline strong {
    font-weight: 800;
}

/* ============================================================
   Restaurant menu page — #99 Option B (mirror Disney's sections)
   ------------------------------------------------------------
   Toolbar (meal-period buttons + columns/sort/filters) → optional
   Top Rated carousel → <details> accordions for each Disney sub-
   section → item cards with thumb / main / side three-column
   layout. Replaces the prior Food/Drinks/Snacks bucket layout on
   this surface. Bucket classifier still drives homepage filters +
   search (unchanged elsewhere).
   ============================================================ */

/* === Toolbar (meal entry + view controls) ============================== */
.menu-toolbar {
    background: var(--color-white);
    border: var(--card-border);
    border-radius: var(--radius-card);
    padding: 12px 16px;
    margin: 16px 0 20px;
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}
/* Mobile: drop the "Menu:" label, tighten the meal-button chrome,
   and switch the toolbar to a 2-column grid (1fr auto) so meals
   take all available width and controls (Sort + Filters) sit
   at their natural width on the right. Grid is more predictable
   than flex here — the previous flex + auto-margin combos kept
   collapsing meals to 0 width. Brandon 2026-06-19. */
@media (max-width: 768px) {
    /* Mobile toolbar: exactly 2 rows.
         Row 1: search input (1fr) + stacked sort/filter (auto)
         Row 2: meal-period pills, full-width scrollable strip
       Cols toggle hidden — column-count isn't meaningful on a
       single-column mobile layout. Brandon 2026-06-23. */
    .menu-toolbar {
        display: grid;
        grid-template-columns: 1fr auto;
        grid-template-rows: auto auto;
        align-items: center;
        gap: 8px;
        flex-wrap: initial;
    }
    .menu-toolbar-search {
        grid-column: 1;
        grid-row: 1;
    }
    .menu-toolbar-controls {
        grid-column: 2;
        grid-row: 1;
        margin-left: 0;
        flex-direction: column;
        align-items: stretch;
        gap: 6px;
    }
    .menu-toolbar-meals {
        grid-column: 1 / -1;
        grid-row: 2;
        gap: 6px;
        min-width: 0;
        overflow-x: auto;
        scrollbar-width: none;
    }
    .menu-toolbar-meals::-webkit-scrollbar { display: none; }
    .menu-toolbar-meals-label { display: none; }
    .menu-toolbar-meal-btn {
        padding: 5px 10px;
        font-size: 0.85rem;
        white-space: nowrap;
        flex-shrink: 0;
    }
    .menu-toolbar-cols {
        display: none;
    }
    /* Sort + Filters: smaller icon buttons so the stacked column
       sits compactly next to the search input. */
    .menu-toolbar-controls > .menu-toolbar-filters-btn,
    .menu-toolbar-controls > .search-toolbar-sort > summary.filter-sheet-trigger {
        width: 32px;
        height: 32px;
    }
    .menu-toolbar-controls .filter-sheet-trigger-icon {
        width: 16px;
        height: 16px;
    }
}
.menu-toolbar-meals {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}
.menu-toolbar-meals-label {
    font-weight: 600;
    color: var(--color-text-light);
}
/* True pill (#153 item 11) — bumped from 20px to 999px to match
   the design language standardized on /search + homepage. */
.menu-toolbar-meal-btn {
    display: inline-block;
    padding: 6px 14px;
    border: 1.5px solid var(--color-primary);
    background: transparent;
    border-radius: 999px;
    color: var(--color-primary);
    font: inherit;
    font-weight: 600;
    font-size: 0.95rem;
    cursor: pointer;
}
.menu-toolbar-meal-btn:hover,
.menu-toolbar-meal-btn.is-active {
    background: var(--color-primary);
    color: var(--color-white);
}
.menu-toolbar-controls {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

/* In-menu search input (#200). Full-width row at the top of the
   toolbar on every viewport. Input uses the site's standard
   .form-input chrome (same border, radius, font, padding as every
   other text input on the site); we just add left padding to make
   room for the absolutely-positioned magnifying-glass icon
   (Brandon 2026-06-23 — was a divergent pill style). */
.menu-toolbar-search {
    flex: 1 1 100%;
    position: relative;
    display: flex;
    align-items: center;
}
.menu-toolbar-search-icon {
    position: absolute;
    left: 14px;
    color: var(--color-text-light);
    pointer-events: none;
}
.menu-toolbar-search-input.form-input {
    padding-left: 38px;
}

/* Columns toggle — segmented pair of icon buttons. Hidden on mobile
   since single-column is forced there. */
/* Single/two-column toggle group — segmented pill, 44px tall to
   match the Sort + Filters buttons in the same toolbar row. */
.menu-toolbar-cols {
    display: inline-flex;
    align-items: stretch;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    overflow: hidden;
    background: var(--color-bg-light);
    height: 44px;
}
.menu-toolbar-cols-btn {
    border: 0;
    background: transparent;
    padding: 0 14px;
    cursor: pointer;
    color: var(--color-text-light);
    display: inline-flex;
    align-items: center;
    justify-content: center;
}
.menu-toolbar-cols-btn:hover {
    color: var(--color-primary);
}
.menu-toolbar-cols-btn.is-active {
    background: var(--color-header);
    color: var(--color-white);
}
/* Hidden on mobile — single column is forced there due to width
   constraints, so the toggle is meaningless. Sort + Filters
   fit on one toolbar line without it. */
@media (max-width: 768px) {
    .menu-toolbar-cols { display: none; }
}

/* Filters trigger — icon-only round circle (#153 item 13),
   matching the /search Filters button. Same 44px footprint, same
   two-tone neutral chrome, same coral active state. */
.menu-toolbar-filters-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    background: var(--color-bg-light);
    border: 1px solid var(--color-border);
    border-radius: 50%;
    cursor: pointer;
    color: var(--color-text);
    transition: background 0.15s ease, border-color 0.15s ease;
}
.menu-toolbar-filters-btn:hover {
    background: var(--color-bg);
    border-color: var(--color-text-light);
}
.menu-toolbar-filters-btn[aria-expanded="true"] {
    background: var(--color-primary);
    color: var(--color-white);
    border-color: var(--color-primary);
}

/* Filter panel — visually merges into the toolbar above when expanded.
   Pairs with .menu-toolbar.is-expanded which flattens the toolbar's
   bottom corners + zeros its bottom margin so the two divs read as
   one container with the filters as a drawer extension. */
.menu-toolbar.is-expanded {
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
    margin-bottom: 0;
}
.menu-filter-panel {
    margin: 0 0 20px;
    padding: 14px 18px;
    background: var(--color-white);
    border: var(--card-border);
    border-top: 0;
    border-radius: 0 0 var(--radius-card) var(--radius-card);
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    align-items: center;
}
.menu-filter-panel[hidden] { display: none; }
.menu-filter-pills {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    flex: 1;
    min-width: 0;
}
.menu-filter-pill-icon {
    font-size: 0.95rem;
}

/* === Top Rated carousel ================================================
   Matches the Popular Items pattern on the restaurant detail page. */
.menu-top-rated {
    margin: 0 0 20px;
}
.menu-top-rated-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-bottom: 8px;
}
.menu-top-rated-title {
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--color-header);
    margin: 0;
}
.menu-top-rated-hint {
    font-size: 0.75rem;
    color: var(--color-text-light);
}
.menu-top-rated-row {
    display: flex;
    gap: 12px;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    padding-bottom: 8px;
}
.menu-top-rated-card {
    flex: 0 0 160px;
    scroll-snap-align: start;
    display: block;
    text-decoration: none;
    color: var(--color-text);
}
@media (max-width: 600px) {
    /* Smaller cards on phones so 3 fit in view with a peek of the
       4th — signals there's more to scroll. The default 160px only
       let 2 cards land per viewport (Brandon 2026-06-23). */
    .menu-top-rated-card {
        flex: 0 0 108px;
    }
    .menu-top-rated-row {
        gap: 10px;
    }
    .menu-top-rated-thumb-letter {
        font-size: 1.3rem;
    }
}
.menu-top-rated-thumb {
    position: relative;
    aspect-ratio: 1/1;
    border-radius: var(--radius-card);
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 6px;
    background-size: cover;
    background-position: center;
    overflow: hidden;
}
/* hsl-letter placeholder. Background hue set inline (crc32 hash
   of the name); same treatment as Popular Items + /search
   entity-tiles. */
.menu-top-rated-thumb-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
}
.menu-top-rated-thumb-letter {
    color: rgba(255, 255, 255, 0.92);
    font-size: 1.6rem;
    font-weight: 700;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
    line-height: 1;
}
/* Badge wrapper positions the tonal pill at the thumb's top-right.
   The wrapper has no chrome of its own — renderThumbsBadge() renders
   the colored pill inside. (#153 item 9) */
.menu-top-rated-badge {
    position: absolute;
    top: 8px;
    right: 8px;
    display: inline-flex;
    align-items: center;
}
/* On mobile the Top Rated cards shrink to 108px (see the @media
   block above). The vote-count suffix on the thumbs-badge (#340)
   makes the pill too wide to fit at that width, so hide the count
   in THIS placement only — the sample-size disclosure still shows
   on the main entity-tile grid and on desktop Top Rated cards.
   (Brandon 2026-07-15) */
@media (max-width: 600px) {
    .menu-top-rated-badge .thumbs-badge-count {
        display: none;
    }
}
.menu-top-rated-name {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: 0.85rem;
    font-weight: 600;
    line-height: 1.2;
}

/* Wrap each meal-period's content in a white card so the menu
   page joins the rhythm of restaurant + menu-item detail pages
   (Brandon 2026-06-21). Toolbar stays outside the card; each
   menu-page-section is a coherent white panel. */
.menu-page-section {
    background: var(--color-white);
    border: var(--card-border);
    border-radius: var(--radius-card);
    padding: 14px 16px 16px;
    margin: 0 0 16px;
}
@media (max-width: 600px) {
    .menu-page-section {
        padding: 10px 10px 12px;
    }
}

/* === Sub-section accordions (Disney's structure mirrored) ============== */
.menu-section-block {
    background: var(--color-bg-light);
    border: var(--card-border);
    border-radius: var(--radius);
    margin: 0 0 10px;
    overflow: hidden;
}
.menu-section-block[open] {
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
}
.menu-section-summary {
    cursor: pointer;
    padding: 12px 16px;
    background: #f3f4f6;
    border-left: 3px solid #cbd0d8;
    list-style: none;
    display: flex;
    align-items: center;
    gap: 8px;
    user-select: none;
    transition: background 0.15s;
}
.menu-section-summary::-webkit-details-marker { display: none; }
.menu-section-summary:hover { background: #eaecef; }
/* The most recently clicked summary keeps :focus, and some browsers
   tint focused summaries faintly darker. Lock the focused-but-not-
   hovered background to the resting tone so collapsed headings all
   read identically (Brandon 2026-06-20). */
.menu-section-summary:focus:not(:hover) { background: #f3f4f6; }
.menu-section-summary:focus { outline: none; }
.menu-section-summary:focus-visible { outline: 2px solid var(--color-primary); outline-offset: -2px; }
.menu-section-summary::before {
    content: "▸";
    color: var(--color-text-light);
    font-size: 0.85rem;
    transition: transform 0.15s;
}
.menu-section-block[open] > .menu-section-summary::before {
    transform: rotate(90deg);
}
.menu-section-name {
    font-weight: 700;
    font-size: 1rem;
    flex: 1;
    color: var(--color-header);
}
.menu-section-count {
    color: var(--color-text-light);
    font-size: 0.82rem;
    font-weight: 500;
}
/* True grid (Brandon 2026-06-19) — column-gap dropped so the
   cells touch directly. Vertical divider becomes border-right on
   the left-column cards (nth-child(odd)); horizontal divider is
   the existing border-top on each row. With no gap between cells,
   the two border families meet at perfect crosses instead of
   floating with empty corridors between them. Cards keep their
   own 14×16 internal padding so content still has breathing room
   from the borders. */
.menu-section-items {
    padding: 4px 0;
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
}
.menu-section-items .menu-item-card:nth-child(odd) {
    border-right: 1px solid var(--color-border);
}
.menu-toolbar[data-cols="1"] ~ * .menu-section-items,
.menu-toolbar[data-cols="1"] ~ .menu-page-section .menu-section-items {
    grid-template-columns: 1fr;
}
.menu-toolbar[data-cols="1"] ~ * .menu-section-items .menu-item-card:nth-child(odd) {
    border-right: 0;
}
@media (max-width: 768px) {
    .menu-section-items {
        grid-template-columns: 1fr;
    }
    .menu-section-items .menu-item-card:nth-child(odd) {
        border-right: 0;
    }
}

/* === Item cards ========================================================
   Three-column flex: thumb (LEFT) / main (FLEX) / side (RIGHT). */
.menu-item-card {
    position: relative;
    display: flex;
    align-items: flex-start;
    padding: 14px 16px;
    border-top: 1px solid var(--color-border);
    gap: 16px;
    transition: background 0.12s;
}
.menu-item-card:hover {
    background: rgba(245, 193, 78, 0.08);
}
.menu-section-items .menu-item-card:nth-child(-n+2) {
    border-top: 0;
}
.menu-toolbar[data-cols="1"] ~ * .menu-section-items .menu-item-card:nth-child(-n+2) {
    border-top: 1px solid var(--color-border);
}
.menu-toolbar[data-cols="1"] ~ * .menu-section-items .menu-item-card:first-child {
    border-top: 0;
}
@media (max-width: 768px) {
    .menu-section-items .menu-item-card:nth-child(-n+2) {
        border-top: 1px solid var(--color-border);
    }
    .menu-section-items .menu-item-card:first-child {
        border-top: 0;
    }
}

/* Bigger thumb (Brandon 2026-06-19) mirroring /search venue cards
   and restaurant Popular Items — 88px mobile, 96px desktop. The
   bookmark overhangs the thumb's right edge into the card body,
   so overflow stays visible; background-size: cover still clips
   the image to the thumb's bounds without needing overflow:hidden. */
.menu-item-thumb {
    position: relative;
    width: 88px;
    height: 88px;
    border-radius: var(--radius);
    flex-shrink: 0;
    background-size: cover;
    background-position: center;
}
@media (min-width: 769px) {
    .menu-item-thumb {
        width: 96px;
        height: 96px;
    }
}
/* Bookmark moved out of the thumb and into the title row
   (Brandon 2026-06-19). Override the base .entity-tile-bookmark
   absolute positioning so the button sits inline at the end of
   the title row, with margin-left: auto pushing it past the
   title text. Same 28px size as everywhere else on the site;
   photo stays fully visible underneath. */
.menu-item-title-row .entity-tile-bookmark {
    position: static;
    top: auto;
    right: auto;
    flex-shrink: 0;
    margin-left: auto;
}
/* hsl-letter placeholder. Background hue set inline (crc32 hash
   of the name); same treatment used across the site. */
.menu-item-thumb-empty {
    display: flex;
    align-items: center;
    justify-content: center;
}
.menu-item-thumb-letter {
    color: rgba(255, 255, 255, 0.92);
    /* Smaller font here than the larger thumbs because .menu-item-
       thumb is only 56×56 — a 1.6rem letter would crowd. */
    font-size: 1.2rem;
    font-weight: 700;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
    line-height: 1;
}
/* Camera-SVG placeholder — sized smaller for the compact 56×56
   menu-item thumb (#153 item 15). */
.menu-item-thumb-camera {
    width: 22px;
    height: 22px;
    color: rgba(255, 255, 255, 0.92);
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.15));
}

.menu-item-main {
    flex: 1;
    min-width: 0;
}
.menu-item-title-row {
    display: flex;
    align-items: center;
    gap: 10px;
}
.menu-item-title {
    margin: 0 0 4px;
    font-size: 1rem;
    font-weight: 600;
    min-width: 0;
}
.menu-item-title a {
    color: var(--color-header);
    text-decoration: none;
}
.menu-item-title a:hover {
    color: var(--color-primary);
}
.menu-item-add {
    flex-shrink: 0;
}
.menu-item-desc {
    margin: 0;
    color: var(--color-text-light);
    font-size: 0.9rem;
    line-height: 1.4;
}
.menu-item-tags {
    margin-top: 8px;
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
}
.menu-item-tag {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 8px 3px 6px;
    background: #f3f4f6;
    border-radius: var(--radius-card);
    font-size: 0.72rem;
    font-weight: 500;
    color: var(--color-text);
    line-height: 1.2;
    white-space: nowrap;
}

/* Right column — rating badge OR Rate it pill, then price, then note. */
.menu-item-side {
    text-align: right;
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 4px;
}
.menu-item-price {
    font-weight: 700;
    font-size: 1rem;
    color: var(--color-primary-dark);
}
.menu-item-price-note {
    font-size: 0.8rem;
    color: var(--color-text-light);
}
/* Legacy duplicate .thumbs-badge definition + .thumbs-{tone}
   (un-prefixed) classes lived here; removed Brandon 2026-06-21
   when the canonical no-pill rule at ~line 1099 became the only
   definition. The admin menu-mirror preview uses its own
   .mirror-thumbs-{tone} namespace and is unaffected. */

/* "Rate it" pill on items without ratings yet. Same pill geometry as
   the thumbs-badge but with a primary-color outline that invites the
   first vote. Links to the item detail page where the full review
   form lives. */
.menu-rate-btn {
    display: inline-flex;
    align-items: center;
    padding: 5px 12px;
    background: var(--color-white);
    border: 1px solid var(--color-primary);
    border-radius: var(--radius-lg);
    color: var(--color-primary);
    font-size: 0.82rem;
    font-weight: 700;
    line-height: 1;
    text-decoration: none;
    cursor: pointer;
    transition: background 0.12s, color 0.12s;
}
.menu-rate-btn:hover {
    background: var(--color-primary);
    color: var(--color-white);
}

/* === Mobile ============================================================ */
@media (max-width: 600px) {
    .menu-toolbar {
        padding: 10px 12px;
        gap: 10px;
    }
    .menu-toolbar-meals,
    .menu-toolbar-controls {
        width: 100%;
        margin-left: 0;
    }
    .menu-toolbar-meal-btn {
        flex: 1;
        text-align: center;
        padding: 6px 10px;
    }
    .menu-toolbar-controls {
        justify-content: space-between;
    }
    .menu-toolbar-sort { flex: 1; }
    .menu-filter-panel {
        flex-direction: column;
        align-items: stretch;
    }
    .menu-item-card {
        padding: 10px 10px;
        gap: 10px;
    }
    .menu-item-thumb {
        width: 48px;
        height: 48px;
    }
}

/* Prix-fixe / buffet / character-dining pricing banner. Surfaces the
   per-person price + any menu-level note above the sections, so users
   understand the pricing context before scanning items (most of which
   don't carry individual prices in these models). */
.menu-pricing-banner {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 12px;
    padding: 10px 14px;
    margin: 0 0 16px;
    background: var(--color-primary-tint, #fff5f3);
    border: 1px solid rgba(255, 90, 71, 0.25);
    border-radius: var(--radius-card);
    font-size: 0.92rem;
}
.menu-pricing-banner-tag {
    padding: 2px 10px;
    background: var(--color-primary);
    color: var(--color-white);
    border-radius: var(--radius-lg);
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}
.menu-pricing-banner-price {
    font-weight: 700;
    color: var(--color-primary-dark);
}
.menu-pricing-banner-note {
    flex: 1;
    min-width: 0;
    color: var(--color-text);
    font-size: 0.88rem;
}
@media (max-width: 600px) {
    /* Tighten the banner so the tag + combined "$X adult · $Y
       child" price line sits comfortably on one row. The optional
       note wraps to its own second line if present (Brandon
       2026-06-23). */
    .menu-pricing-banner {
        padding: 8px 12px;
        gap: 8px;
        font-size: 0.88rem;
    }
    .menu-pricing-banner-tag {
        padding: 2px 8px;
        font-size: 0.7rem;
    }
    .menu-pricing-banner-note {
        flex: 1 1 100%;
        font-size: 0.82rem;
    }
}

/* Cookie-consent banner (#83 → #11).
   Fixed to the bottom of the viewport, slim, dismissable. Hidden by
   the server when the user has already consented (cookie or DB). */
.cookie-banner {
    position: fixed;
    left: 16px;
    right: 16px;
    bottom: 16px;
    z-index: 950;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 16px;
    background: var(--color-surface, #fff);
    border: 1px solid var(--color-border, #d0d7de);
    box-shadow: 0 4px 18px rgba(0, 0, 0, 0.12);
    border-radius: var(--radius-card);
    padding: 14px 18px;
}
.cookie-banner-text {
    flex: 1 1 280px;
    min-width: 0;
    color: var(--color-text);
    font-size: 0.92rem;
    line-height: 1.45;
}
.cookie-banner-text a {
    color: var(--color-primary);
    text-decoration: underline;
}
.cookie-banner-accept {
    flex: 0 0 auto;
}

/* === List tags + browse page (#254) ================================== */

/* Tag row on the list-detail heading + the inline Edit button.
   Mobile: single-row horizontal scroll instead of wrapping into
   multiple lines so the heading stays tight (Brandon 2026-06-26). */
.list-tag-row {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 6px 0 0;
    align-items: center;
}
@media (max-width: 600px) {
    .list-tag-row {
        flex-wrap: nowrap;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        justify-content: flex-start;
        /* Negative side margin lets the scroll area run into the
           heading-card edge so chips can scroll fully right. */
        margin-left: -16px;
        margin-right: -16px;
        padding: 0 16px;
    }
    .list-tag-row::-webkit-scrollbar { display: none; }
    .list-tag-chip-display { flex-shrink: 0; }
    .list-tag-edit-btn { flex-shrink: 0; }
}
.list-tag-chip-display {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 10px;
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: 999px;
    font-size: 0.82rem;
    color: var(--color-text);
    text-decoration: none;
}
.list-tag-chip-display:hover {
    background: var(--color-white);
    border-color: var(--color-text-light);
    text-decoration: none;
}
.list-tag-edit-btn {
    background: transparent;
    border: 1px dashed var(--color-text-light);
    color: var(--color-text-light);
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 0.78rem;
    cursor: pointer;
}
.list-tag-edit-btn:hover {
    color: var(--color-primary);
    border-color: var(--color-primary);
}

/* Tag-picker chip grid used in the create-list + edit-list modals. */
.list-tag-picker {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    max-height: 280px;
    overflow-y: auto;
    padding: 6px;
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    background: var(--color-bg);
}
.list-tag-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px 12px;
    background: var(--color-white);
    border: 1px solid var(--color-border);
    border-radius: 999px;
    font-size: 0.85rem;
    cursor: pointer;
    user-select: none;
}
.list-tag-chip input { display: none; }
.list-tag-chip:hover { border-color: var(--color-primary); }
.list-tag-chip input:checked + span {
    color: var(--color-primary);
    font-weight: 600;
}
.list-tag-chip:has(input:checked) {
    background: var(--color-primary-tint, #ffe5e0);
    border-color: var(--color-primary);
}

/* /lists/browse filter rail. */
.lists-browse-filters {
    margin: 0 0 16px;
}
.lists-browse-filters-row {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: stretch;
    margin-bottom: 12px;
}
.lists-browse-filters-row input[type="search"] { flex: 1; min-width: 200px; }
.lists-browse-filters-row select { max-width: 180px; }
.lists-browse-tag-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}
.lists-browse-tag-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px 12px;
    background: var(--color-white);
    border: 1px solid var(--color-border);
    border-radius: 999px;
    font-size: 0.82rem;
    color: var(--color-text);
    text-decoration: none;
}
.lists-browse-tag-chip:hover {
    border-color: var(--color-primary);
    text-decoration: none;
}
.lists-browse-tag-chip.is-active {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: var(--color-white);
}
.lists-browse-count {
    color: var(--color-text-light);
    font-size: 0.9rem;
    margin: 0 0 16px;
}
/* List description — hidden on mobile to keep cards compact;
   shown clamped to 2 lines on desktop where there's room. Used on
   /lists/browse public discovery cards (Brandon 2026-06-26). */
.list-card-desc { display: none; }
@media (min-width: 769px) {
    .list-card-desc {
        display: -webkit-box;
        color: var(--color-text-light);
        font-size: 0.78rem;
        line-height: 1.3;
        margin: 0;
        overflow: hidden;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
    }
}

/* === Creator badge (#270) =========================================== */
/* Color: X.com / Twitter "verified" blue. The shorthand for "trusted /
   authenticated" most users already recognize across services. */
.creator-badge {
    display: inline-block;
    background: #1d9bf0;
    color: #fff;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    vertical-align: middle;
    margin-left: 6px;
}
.creator-badge-sm {
    padding: 0 5px;
    font-size: 0.65rem;
    margin-left: 2px;
}

/* === Result tabs on /search (#273) ================================== */
/* Two-tab switch between Restaurants and Menu Items, replacing the
   stacked-sections layout when a query is present. */
.result-tabs {
    display: flex;
    gap: 4px;
    margin: 0 0 16px;
    border-bottom: 1px solid var(--color-border);
}
.result-tab {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 10px 16px;
    color: var(--color-text-light);
    font-weight: 600;
    text-decoration: none;
    border-bottom: 2px solid transparent;
    margin-bottom: -1px;
    transition: color 120ms ease, border-color 120ms ease;
}
.result-tab:hover { color: var(--color-text); text-decoration: none; }
.result-tab.is-active {
    color: var(--color-primary);
    border-bottom-color: var(--color-primary);
}
.result-tab-count {
    display: inline-block;
    background: var(--color-bg);
    color: var(--color-text-light);
    padding: 1px 8px;
    border-radius: 999px;
    font-size: 0.8rem;
    font-weight: 600;
    min-width: 24px;
    text-align: center;
}
.result-tab.is-active .result-tab-count {
    background: var(--color-primary-tint, #ffe5e0);
    color: var(--color-primary);
}
/* Hide the inactive result pane. Both panes are server-rendered
   so client-side tab switches are instant (no re-fetch). */
.result-tab-pane.is-hidden-tab { display: none; }

/* === List toolbar (#273 follow-up — search/sort/filter/group) ====== */
.list-toolbar {
    margin: 8px 0 12px;
}
/* Toolbar bar reuses the shared .search-toolbar-bar /
   .search-toolbar-input-group / .search-toolbar-actions chrome
   from /search (Brandon 2026-06-26 — consistent affordance
   site-wide). One local override: tighten the bottom margin so
   the chip strip sits closer below. */
.list-toolbar-bar {
    margin-bottom: 8px;
}
/* Single-row horizontally scrolling chip strip. Wraps were eating
   3+ rows of vertical space on busy lists (Brandon 2026-06-26). */
.list-toolbar-chips {
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    gap: 6px;
    align-items: center;
    padding-bottom: 2px;
}
.list-toolbar-chips::-webkit-scrollbar { display: none; }
.list-toolbar-chip { flex-shrink: 0; }
.list-toolbar-chip-sep { flex-shrink: 0; }
.list-toolbar-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px 12px;
    background: var(--color-white);
    border: 1px solid var(--color-border);
    border-radius: 999px;
    font-size: 0.82rem;
    color: var(--color-text);
    cursor: pointer;
}
.list-toolbar-chip:hover { border-color: var(--color-primary); }
.list-toolbar-chip.is-active {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: var(--color-white);
}
.list-toolbar-chip-count {
    opacity: 0.75;
    font-size: 0.78rem;
}
.list-toolbar-chip-sep {
    display: inline-block;
    width: 1px;
    height: 20px;
    background: var(--color-border);
    margin: 0 4px;
}
/* Group heading inserted into the entity-tile-list when group mode
   is on. Looks like a subtle subhead under the toolbar. */
.list-group-heading {
    grid-column: 1 / -1;
    padding: 14px 0 6px;
    font-weight: 600;
    color: var(--color-text);
    border-bottom: 1px solid var(--color-border);
    margin-bottom: 4px;
}
.list-group-heading:first-child { padding-top: 4px; }
/* "No matches" empty state for the toolbar's filter-down to zero
   case. De-emphasized detour link to broader /search. */
.list-no-matches {
    text-align: center;
    padding: 32px 16px;
    color: var(--color-text-light);
}
.list-no-matches-detour {
    margin-top: 8px;
    font-size: 0.88rem;
}
.list-no-matches-detour a {
    color: var(--color-text-light);
    text-decoration: underline;
    text-decoration-style: dotted;
}
.list-no-matches-detour a:hover { color: var(--color-primary); }

/* === Per-card edit-pencil overlay on /lists (Brandon 2026-06-26) === */
/* Wrapper anchors the absolute overlay button to the .list-card. */
.list-card-wrap {
    position: relative;
}
.list-card-edit-overlay {
    position: absolute;
    top: 6px;
    right: 6px;
    width: 26px;
    height: 26px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.92);
    border: 1px solid var(--color-border);
    border-radius: 999px;
    color: var(--color-text-light);
    cursor: pointer;
    transition: color 120ms, border-color 120ms;
    z-index: 2;
}
.list-card-edit-overlay:hover {
    color: var(--color-primary);
    border-color: var(--color-primary);
}

/* === Char counter on form labels === */
.char-counter {
    float: right;
    color: var(--color-text-light);
    font-size: 0.75rem;
    font-weight: 400;
    margin-top: 2px;
}

/* === Destructive delete button inside the edit modal === */
.list-delete-btn {
    background: transparent;
    color: #c62828;
    border: 1px solid #c62828;
    font-weight: 600;
}
.list-delete-btn:hover {
    background: #c62828;
    color: var(--color-white);
}

/* =====================================================================
   Festivals (#314 — Festivals Phase 3 public surfaces)
   ===================================================================== */

/* Homepage hero strip — coral pill banner just above the Popular tabs.
   Renders only when at least one festival is active. */
.home-festival-banner-section {
    padding-top: 16px;
    padding-bottom: 0;
}
/* Larger 2-line banner with more visual weight (Brandon 2026-07-02).
   Moved above Browse by Park so it's above the first-scroll fold.
   Rounded rectangle (not pill) so the two-line copy reads properly. */
.home-festival-banner {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 16px 20px;
    background: var(--color-primary);
    color: var(--color-white);
    border-radius: var(--radius-card);
    text-decoration: none;
    box-shadow: 0 6px 18px rgba(255, 90, 71, 0.32);
    transition: transform 150ms ease, box-shadow 150ms ease, background 150ms ease;
}
.home-festival-banner:hover {
    color: var(--color-white);
    background: var(--color-primary-dark);
    transform: translateY(-1px);
    box-shadow: 0 8px 22px rgba(255, 90, 71, 0.38);
}
/* Softer palette for the pre-run "upcoming" banner so an active
   festival always visually dominates when both exist (only one
   ever renders — but the visual distinction reads even standalone
   as "coming vs happening now"). */
.home-festival-banner-upcoming {
    background: var(--color-header);
    box-shadow: 0 6px 18px rgba(13, 43, 82, 0.28);
}
.home-festival-banner-upcoming:hover {
    background: #1a3a6b;
    box-shadow: 0 8px 22px rgba(13, 43, 82, 0.32);
}
.home-festival-banner-icon {
    font-size: 1.8em;
    line-height: 1;
    flex-shrink: 0;
}
/* Optional festival hero thumbnail — 48px round tile when the
   festival has a hero_image_url; falls back to the emoji icon. */
.home-festival-banner-thumb {
    flex-shrink: 0;
    display: block;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background-color: rgba(255, 255, 255, 0.15);
    background-size: cover;
    background-position: center;
    border: 2px solid rgba(255, 255, 255, 0.5);
}
.home-festival-banner-text {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
    line-height: 1.3;
}
.home-festival-banner-title {
    font-size: 1.05rem;
    font-weight: 700;
    letter-spacing: -0.01em;
}
.home-festival-banner-sub {
    font-size: 0.85rem;
    opacity: 0.9;
    font-weight: 500;
}
.home-festival-banner-arrow { flex-shrink: 0; opacity: 0.9; }
@media (max-width: 480px) {
    .home-festival-banner { padding: 12px 14px; gap: 10px; }
    .home-festival-banner-thumb { width: 40px; height: 40px; }
    .home-festival-banner-title { font-size: 0.95rem; }
    .home-festival-banner-sub { font-size: 0.78rem; }
}

/* Hero collage center badge — swap to a wine glass silhouette when
   a festival exists. Keeps the coral tint from the base .home-hero-
   badge rule; just documents the class here for clarity. */
.home-hero-badge-festival { /* uses .home-hero-badge base styles */ }

/* /festivals index — three sections (active / upcoming / past) sharing
   the same .festival-card chrome, with .festivals-archive-grid for the
   past-years tile strip. */
.festivals-index { padding-bottom: 32px; }
.festivals-section { margin: 28px 0; }
.festivals-section-title {
    font-size: 1.3rem;
    margin: 0 0 14px;
    color: var(--color-text);
}
.festivals-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: 18px;
}
.festivals-grid-large {
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
}
.festival-card {
    display: flex;
    flex-direction: column;
    background: var(--color-white);
    border-radius: 14px;
    overflow: hidden;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.06);
    text-decoration: none;
    color: var(--color-text);
    transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.festival-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.09);
    color: var(--color-text);
}
.festival-card-hero {
    aspect-ratio: 16 / 9;
    background-color: var(--color-primary-tint);
    background-size: cover;
    background-position: center;
    position: relative;
}
.festival-card-pill {
    position: absolute;
    top: 12px;
    left: 12px;
    background: var(--color-primary);
    color: var(--color-white);
    font-size: 0.75rem;
    font-weight: 700;
    padding: 4px 10px;
    border-radius: 999px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
}
.festival-card-body { padding: 14px 16px 16px; }
.festival-card-title { font-size: 1.1rem; margin: 0 0 6px; }
.festival-card-meta { color: var(--color-text-muted, #666); font-size: 0.9rem; margin: 0 0 8px; }
.festival-card-blurb { font-size: 0.92rem; line-height: 1.45; margin: 0 0 12px; color: var(--color-text); }
.festival-card-cta {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: var(--color-primary);
    font-weight: 600;
    font-size: 0.92rem;
}

/* Past-festival archive treatment — flat grid of tiny chips. */
.festivals-section-past { opacity: 0.95; }
.festivals-series { margin: 18px 0; }
.festivals-series-title {
    font-size: 1rem;
    font-weight: 600;
    margin: 0 0 8px;
    color: var(--color-text);
}
.festivals-archive-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 8px;
}
.festival-archive-tile {
    display: flex;
    flex-direction: column;
    padding: 10px 12px;
    background: var(--color-white);
    border: 1px solid var(--color-border, #e5e5e5);
    border-radius: 10px;
    text-decoration: none;
    color: var(--color-text);
    transition: background 0.12s ease, border-color 0.12s ease;
}
.festival-archive-tile:hover {
    background: var(--color-primary-tint);
    border-color: var(--color-primary-light);
    color: var(--color-text);
}
.festival-archive-year { font-weight: 700; font-size: 1.05rem; }
.festival-archive-dates { font-size: 0.8rem; color: var(--color-text-muted, #666); }

/* /festivals/{slug} hub — hero, tabs, panes. Reuses .result-tabs +
   .result-tab-pane from /search so the toggle behavior stays
   consistent. */
.festival-hub { padding-bottom: 40px; }
.festival-hub-past { /* Optional: future muted archive treatment. */ }
/* Festival heading refactor (Brandon 2026-07-02): use the site's
   standard .page-heading-card chrome instead of a coral-gradient
   custom hero. Optional festival hero image sits as its OWN
   surface above the heading card — matches how other detail pages
   compose photos above headings, not inside them. */
.festival-hero-image {
    height: 200px;
    margin: 8px 0 12px;
    border-radius: var(--radius-card);
    background-size: cover;
    background-position: center;
    box-shadow: 0 2px 12px rgba(13, 43, 82, 0.12);
}
@media (min-width: 769px) {
    .festival-hero-image { height: 280px; }
}
/* Status pill sits inside .page-heading-card-title, above the H1. */
.festival-status-pill {
    display: inline-block;
    padding: 3px 10px;
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    border-radius: 999px;
    margin-bottom: 6px;
}
.festival-status-pill-active   { background: var(--color-primary); color: var(--color-white); }
.festival-status-pill-upcoming { background: var(--color-header);  color: var(--color-white); }
.festival-status-pill-past     { background: var(--color-bg);      color: var(--color-text-light); }
.festival-heading-description {
    max-width: 60ch;
    margin-left: auto;
    margin-right: auto;
}
/* Festival items-tab chip row — sits above the .entity-tile-list grid
   and toggles ?type=new|returning on the hub. */
.festival-item-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 16px 0;
}

/* Related-articles: stacks the standard .blog-list-card article cards
   vertically inside a .restaurant-section wrapper. Cards themselves
   use their existing site-wide styling — no festival-specific card
   chrome (Brandon 2026-07-02 — reuse patterns, don't invent). */
.festival-related-articles {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

/* Restaurant + menu-item detail page badges. */
.restaurant-festival-badge {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin: 10px 0 4px;
    padding: 6px 12px;
    background: var(--color-primary);
    color: var(--color-white);
    border-radius: 999px;
    font-weight: 600;
    font-size: 0.88rem;
    text-decoration: none;
}
.restaurant-festival-badge:hover { background: var(--color-primary-dark); color: var(--color-white); }
.restaurant-festival-badge-icon { font-size: 1.05em; }

.menu-item-festival-pill {
    display: inline-block;
    margin: 8px 0 0;
    padding: 4px 10px;
    background: var(--color-primary);
    color: var(--color-white);
    border-radius: 999px;
    font-size: 0.8rem;
    font-weight: 600;
}
.menu-item-festival-pill-returning { background: var(--color-primary-dark); }

/* Disney Dining Plan menu-item pill (#333). Piggybacks on the
   festival-pill shape but recolors to amber. The -est variant is used
   when eligibility is inferred rather than confirmed. The standalone
   .restaurant-ddp-badge that used to live here was folded into the
   inline .badge badge-ddp on the tag row 2026-07-11 so the DDP chip
   sits next to the venue-type badge and reads as one thought
   ("Quick Service · 🎟"). */
.menu-item-ddp-pill {
    background: #FFF3E0;
    color: #B45A0B;
    border: 1px solid #F5C784;
}
.menu-item-ddp-pill-est {
    background: #FFF8E7;
    color: #A26E1B;
    border-style: dashed;
}

/* Tile-thumb festival overlay — small coral wine glass in the
   top-left of the thumb, opposite the bookmark. Renders only when
   the caller passed festival_active = 1 in the tile data. */
.entity-tile-festival {
    position: absolute;
    top: 6px;
    left: 6px;
    width: 22px;
    height: 22px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: var(--color-primary);
    color: var(--color-white);
    border-radius: 50%;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.25);
    pointer-events: none;
}
.entity-tile-festival svg { width: 12px; height: 12px; }

/* Article / guide / page → linked-festival pill (#315 — Festivals
   Phase 4 editorial linking). Coral pill rendered above the title on
   /blog/{slug} or /guides/{slug} when content.festival_id is set. */
.content-festival-pill-row { margin: 0 0 10px; }
.content-festival-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 12px;
    background: var(--color-primary);
    color: var(--color-white);
    border-radius: 999px;
    font-size: 0.82rem;
    font-weight: 600;
    text-decoration: none;
}
.content-festival-pill:hover { background: var(--color-primary-dark); color: var(--color-white); }

/* Blog index festival filter pills (#315). Horizontal-scroll row of
   chips above the article grid, same shape as /lists/browse tag chips
   so the filter row reads consistently across sibling browse pages. */
.blog-festival-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 0 0 14px;
}
.blog-festival-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px 12px;
    background: var(--color-white);
    border: 1px solid var(--color-border);
    border-radius: 999px;
    font-size: 0.82rem;
    color: var(--color-text);
    text-decoration: none;
}
.blog-festival-chip:hover {
    border-color: var(--color-primary);
    text-decoration: none;
}
.blog-festival-chip.is-active {
    background: var(--color-primary);
    border-color: var(--color-primary);
    color: var(--color-white);
}
.blog-festival-chip-count { opacity: 0.7; }
