/*
Theme Name: Dialtone
Theme URI: https://dialtone.local
Author: Gabriel Haruki Satoh
Author URI: https://github.com/harukisatoh
Description: Custom WordPress theme for the Dialtone project. Designed to work with Elementor and Gravity Forms.
Version: 0.1.0
Requires at least: 6.0
Tested up to: 6.7
Requires PHP: 8.0
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: dialtone
*/

/* =========================================================================
   Dialtone design tokens
   Source of truth: docs/figma-screens.md § Design system (verified).
   ========================================================================= */
:root {
    /* Colors */
    --dt-green: #4f6138; /* primary brand olive */
    --dt-dark-green: #081c13; /* deep brand dark / footer / menu bg */
    --dt-rust: #955323; /* warm accent / products + privacy bg */
    --dt-slate: #9cb6be; /* muted gray-blue secondary */
    --dt-gold: #ebb235; /* accent (rewards 5th star) */
    --dt-black: #000000;
    --dt-white: #ffffff;

    /* Type families */
    --dt-font-display:
        "Work Sans", sans-serif; /* H1, H2, taglines, pills, nav */
    --dt-font-mono: "Roboto Mono", monospace; /* H3, body, captions, eyebrow */
    --dt-font-script: "Beth Ellen", cursive; /* decorative quote (Rewards) */

    /* Type scale (font-size / line-height) */
    --dt-h1-size: 72px;
    --dt-h1-lh: 85px; /* Work Sans 400 */
    --dt-h2-size: 40px; /* Work Sans 500 */
    --dt-h3-size: 20px; /* Roboto Mono 400 */
    --dt-body-size: 16px;
    --dt-body-lh: 1.5; /* Roboto Mono 300 */
    --dt-tagline-size: 20px;
    --dt-tagline-lh: 28px;
    --dt-tagline-track: 0.04em; /* Work Sans 700 */
    --dt-caption-size: 13px; /* Roboto Mono 300 italic */
    --dt-eyebrow-size: 16px; /* Roboto Mono 700 */

    /* Layout */
    --dt-canvas: 1440px;
    --dt-gutter: 100px;
    --dt-radius: 15px; /* card image corner radius */
    --dt-pill-radius: 5px; /* status pill corner radius */
}

/* =========================================================================
   Base typography — set explicitly so Elementor / Gravity Forms / theme
   resets don't fall back to a system stack. Every Dialtone widget inherits
   from these rules.
   ========================================================================= */
html,
body {
    font-family: var(--dt-font-mono);
    font-weight: 300;
    font-size: var(--dt-body-size);
    line-height: var(--dt-body-lh);
    color: var(--dt-white);
    /* Never let decorative overshoot add a horizontal scrollbar: the
       scroll-reveal start transforms (.dt-two-col__content +32px /
       __image-wrap -32px, below) sit off-axis until an element scrolls into
       view, momentarily widening the page on any width — desktop included.
       `clip` (not `hidden`) contains it without creating a scroll container,
       so the fixed nav, pinned subnav, and Leaflet panes stay unaffected.
       Same idiom as `.dt-menu-dynamic`. */
    overflow-x: clip;
}
h1,
h2,
.dt-h1,
.dt-h2 {
    font-family: var(--dt-font-display);
}
h3,
h4,
h5,
h6 {
    font-family: var(--dt-font-mono);
}
/* All Dialtone widgets inherit display+mono families correctly. */
[class*="dt-"],
[class*="dt-"] * {
    font-family: inherit;
}
[class*="dt-"] h1,
[class*="dt-"] h2,
[class*="dt-"] .dt-h1,
[class*="dt-"] .dt-h2 {
    font-family: var(--dt-font-display);
}

/* =========================================================================
   Full-bleed overrides — make notification bar / main nav / site footer
   widgets stretch edge-to-edge regardless of the Elementor container they
   are dropped into. Elementor wraps each widget in
   `.elementor-widget-container` with default padding + max-widths; we strip
   both for these three widgets.
   ========================================================================= */
/* Elementor wraps each widget in `.elementor-widget-container` with padding,
   and the Theme-Builder header/footer use `.e-con-boxed` containers with a
   max-width. Both fight against an edge-to-edge header/footer. The block
   below neutralises BOTH so the notification bar, main nav, site footer,
   and hero stretch from edge to edge regardless of how the Container was
   configured in the editor. */
[data-elementor-type="header"],
[data-elementor-type="footer"] {
    width: 100%;
}
[data-elementor-type="header"] .e-con,
[data-elementor-type="header"] .e-con-inner,
[data-elementor-type="footer"] .e-con,
[data-elementor-type="footer"] .e-con-inner {
    max-width: 100% !important;
    width: 100% !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
}
.elementor-widget-dt-notification-bar > .elementor-widget-container,
.elementor-widget-dt-main-nav > .elementor-widget-container,
.elementor-widget-dt-site-footer > .elementor-widget-container,
.elementor-widget-dt-hero > .elementor-widget-container {
    padding: 0 !important;
}
.elementor-widget-dt-notification-bar,
.elementor-widget-dt-main-nav,
.elementor-widget-dt-site-footer,
.elementor-widget-dt-hero {
    width: 100% !important;
    max-width: 100% !important;
}
/* The header stacks the notification bar above the nav in a flex container that
   carried Elementor's default 20px row-gap, pushing the nav too far down. Zero
   it so the bar sits flush above the nav (matches Figma). */
[data-elementor-type="header"] .e-con,
[data-elementor-type="header"] .e-con-inner {
    row-gap: 0 !important;
}

/* =========================================================================
   Header overlaps the hero on the Homepage.
   On the Home page, the Elementor header template floats over the hero
   so the storefront photo runs to the top of the viewport.

   Scoped to the `.dt-page--home` swap container (NOT `body.home`): during a
   Swup transition the body-class plugin swaps the <body> class mid-sweep, so a
   `body.home` selector would match the OUTGOING interior page's header too and
   yank it out of flow — making that page's content jump up while it's still
   visible under the reveal mask. The container's slug class is baked server-side
   (header.php) and never changes during a visit, so only the real Home header
   goes absolute. At rest this renders identically to keying off body.home.
   ========================================================================= */
.dt-page--home [data-elementor-type="header"] {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    z-index: 20;
}
.dt-page--home {
    /* Positioning context for the absolute header; it is full-width so the
       header's left:0/right:0 still span edge to edge. Allows the hero to
       extend below the absolute header. */
    position: relative;
}

/* Footer's curline strip overlaps above the page content (the curline tail
   visually leaks into the page).  */
[data-elementor-type="footer"] {
    position: relative;
    z-index: 1;
    margin-top: -120px;
}

/* =========================================================================
   Sticky reveal nav (assets/sticky-main-nav.js).
   A SEPARATE fixed bar — a clone of the page nav — appended to <body>. The real
   header above is left untouched: it stays the static "resting" nav at the top
   of each page and scrolls away normally. This bar is the one that appears /
   disappears:
     • scroll UP   → `.is-shown` → slides down into view (transform)
     • scroll DOWN → remove `.is-shown` → slides back up out of view (transform)
     • reach TOP   → `.is-fading` → fades out in place (opacity), leaving the
                     resting nav visible underneath
   `.dt-no-anim` is used by the JS for a one-frame instant reset (faded → hidden-
   up) so the next reveal is always a clean slide, never a fade-in. JS also keeps
   the bar height in `--dt-header-h` (used by the subnav offset below). */
/* The clone lives outside Elementor's wrapper, so it doesn't inherit Elementor's
   border-box reset. Without this the nav's width:100% + 88px side padding would
   overflow the viewport and clip the right-hand links. */
.dt-sticky-nav,
.dt-sticky-nav * {
    box-sizing: border-box;
}
.dt-sticky-nav {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 60; /* above the pinned subnav (.is-stuck = z-index 50) */
    /* Frosted glass: the current page's background colour at reduced alpha, over
       a blur of the content scrolling beneath. The rgba is published per page by
       sticky-main-nav.js (--dt-sticky-bg, read from the live body background);
       the fallback is dark-green translucent. */
    background: var(--dt-sticky-bg, rgba(8, 28, 19, 0.7));
    -webkit-backdrop-filter: blur(14px);
    backdrop-filter: blur(14px);
    transform: translateY(-100%); /* hidden above the viewport at rest */
    opacity: 1;
    pointer-events: none;
    will-change: transform, opacity;
    transition: transform 0.32s cubic-bezier(0.22, 0.61, 0.36, 1),
                opacity 0.3s ease;
}
.dt-sticky-nav.is-shown {
    transform: translateY(0);
    pointer-events: auto;
}
.dt-sticky-nav.is-fading {
    opacity: 0;
    pointer-events: none;
}
.dt-sticky-nav.dt-no-anim {
    transition: none; /* JS toggles this for an instant, un-animated reset */
}
@media (prefers-reduced-motion: reduce) {
    /* Drop the slide; keep only the gentle opacity fade. */
    .dt-sticky-nav {
        transition: opacity 0.25s ease;
    }
    /* Stop the rewards-mug glow from cycling colors. */
    .dt-rewards-hero__mug-icon {
        animation: none !important;
    }
}

/* =========================================================================
   Utility classes — attach to Elementor widgets via Advanced → CSS Classes.
   These cover design details Elementor can't produce natively, so the look
   stays locked even as the client edits content.
   ========================================================================= */

/* Image with only the right corners rounded (cards, hero side images). */
.dt-round-right,
.dt-round-right img,
.dt-round-right .elementor-widget-container {
    border-radius: 0 var(--dt-radius) var(--dt-radius) 0;
    overflow: hidden;
}

/* Status pill: mixed corners (right side rounded) + drop shadow. */
.dt-pill {
    display: inline-block;
    padding: 4px 14px;
    border-radius: 0 var(--dt-pill-radius) var(--dt-pill-radius) 0;
    box-shadow: 0 4px 4px rgba(0, 0, 0, 0.25);
    font-family: var(--dt-font-display);
    font-weight: 700;
    font-size: 14px;
    letter-spacing: 0.04em;
    color: var(--dt-white);
    text-transform: uppercase;
    line-height: 20px;
}
/* Per Figma: Flagship + Coming Soon share the same pill color on a given
   page (dark-green on Homepage, olive on Locations / Products). */
.dt-pill--dark {
    background: var(--dt-dark-green);
} /* Homepage */
.dt-pill--olive {
    background: var(--dt-green);
} /* Locations / Products */
.dt-pill--coming-soon {
    background: var(--dt-dark-green);
} /* alias of --dark */
.dt-pill--new {
    background: var(--dt-gold);
    color: var(--dt-dark-green);
}

/* Hero scrim: 30% black overlay above a background image.
   Put .dt-scrim on the Container whose background is the hero photo. */
.dt-scrim {
    position: relative;
}
.dt-scrim::after {
    content: "";
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.3);
    pointer-events: none;
    z-index: 0;
}
.dt-scrim > * {
    position: relative;
    z-index: 1;
}

/* Text link followed by the long-arrow illustration (e.g. "About Dialtone →").
   The arrow is an <img> tag injected by render_arrow_link() so it shows the
   real SVG asset, not a stroked line. The .dt-arrow-link__svg span carries a
   currentColor mask fallback for browsers that block external SVGs. */
.dt-arrow-link {
    font-family: var(--dt-font-mono);
    font-weight: 400;
    font-size: 18px;
    color: var(--dt-white);
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 16px;
    line-height: 1;
}
.dt-arrow-link__icon {
    display: inline-block;
    width: 101px;
    height: 15px;
    flex-shrink: 0;
    transition: transform 0.2s ease;
}
.dt-arrow-link__icon img,
.dt-arrow-link__icon svg {
    display: block;
    width: 100%;
    height: 100%;
}
.dt-arrow-link:hover .dt-arrow-link__icon {
    transform: translateX(6px);
}

/* Active nav / subnav curved underline. */
.dt-nav-active {
    position: relative;
}
.dt-nav-active::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: -6px;
    height: 2px;
    background: var(--dt-white);
    border-radius: 2px;
}

/* =========================================================================
   Custom Elementor widget styles
   Each widget owns its own scoped block below. Reuse the design tokens
   declared above; never hardcode colors/fonts/sizes here.
   ========================================================================= */

/* Section Heading: H1 left (with optional icon), arrow-link right. */
.dt-section-heading {
    display: flex;
    align-items: center; /* align the right link's text baseline with the H1 baseline */
    justify-content: space-between;
    gap: 32px;
    color: var(--dt-white);
}
.dt-section-heading__title-wrap {
    display: inline-flex;
    align-items: center;
    gap: 18px;
}
.dt-section-heading__icon {
    display: inline-flex;
    flex-shrink: 0;
}
.dt-section-heading__icon img {
    display: block;
    width: 35px;
    height: 35px;
    object-fit: contain;
}
.dt-section-heading__title {
    margin: 0;
    font-family: var(--dt-font-display);
    font-weight: 400;
    font-size: var(
        --dt-h1-size
    ); /* default; overridden inline when client sets font_size */
    line-height: 1.18;
    letter-spacing: 0;
}
.dt-section-heading__title-link {
    display: contents;
    color: inherit;
    text-decoration: none;
}
.dt-section-heading__title a {
    color: inherit;
    text-decoration: none;
    font-weight: inherit;
}
.dt-section-heading__link {
    /* Baseline-aligned to the H1 via the parent's align-items: baseline. */
}

/* =========================================================================
   Privacy Body: asymmetric two-column legal page. "Privacy Policy" H1 at
   left; intro + table of contents + sections in the narrow right column.
   The widget background is transparent so the rust body color shows through.
   Reference: docs/figma-screens.md §7.
   ========================================================================= */
.dt-privacy {
    color: var(--dt-white);
}
.dt-privacy__inner {
    max-width: 1228px;
    margin: 0 auto;
    padding: 96px 16px 0;
    display: grid;
    grid-template-columns: 624px 597px; /* lands the body column at Figma x≈730 */
    column-gap: 0;
    align-items: start;
}
.dt-privacy__title {
    margin: 0;
    font-family: var(--dt-font-display);
    font-weight: 400;
    font-size: var(--dt-h1-size); /* 72px */
    line-height: 1.18;
    letter-spacing: 0;
    color: var(--dt-white);
}
.dt-privacy__body {
    max-width: 597px;
    font-family: var(--dt-font-mono);
    font-weight: 300;
    font-size: var(--dt-body-size); /* 16px */
    line-height: var(--dt-body-lh); /* 1.5 */
    color: var(--dt-white);
}
.dt-privacy__intro p,
.dt-privacy__section-body p {
    margin: 0 0 1.5em;
}
.dt-privacy__intro p:last-child,
.dt-privacy__section-body p:last-child {
    margin-bottom: 0;
}
/* `bolder` against the light-300 body resolves to 400; force real bold. */
.dt-privacy__body strong,
.dt-privacy__body b {
    font-weight: 700;
}
.dt-privacy__toc {
    list-style: disc;
    padding-left: 1.2em;
    margin: 2em 0;
}
.dt-privacy__toc li {
    margin: 0;
}
.dt-privacy__toc a {
    color: inherit;
    text-decoration: none;
}
.dt-privacy__toc a:hover {
    text-decoration: underline;
}
.dt-privacy__section {
    margin-top: 48px;
}
.dt-privacy__section-title {
    margin: 0 0 24px;
    font-family: var(--dt-font-display);
    font-weight: 700;
    font-size: var(--dt-tagline-size); /* 20px */
    line-height: var(--dt-tagline-lh); /* 28px */
    letter-spacing: var(--dt-tagline-track); /* 0.04em */
    text-transform: uppercase;
    color: var(--dt-white);
}
@media (max-width: 1024px) {
    .dt-privacy__inner {
        grid-template-columns: 1fr;
        row-gap: 32px;
        padding: 64px 24px 0;
    }
    .dt-privacy__body {
        max-width: none;
    }
}

/* Notification Bar: 30px full-width bar at the top of the site. */
.dt-notification-bar {
    position: relative;
    width: 100%;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
    /* Symmetric inset reserves room for the absolutely-positioned close (×)
       button on the right so the centred text never slides under it. */
    padding: 0 44px;
}
/* Dismissed via the close button. assets/notification-bar.js sets the
   `dt-notif-dismissed` class on <html> synchronously in the <head> (before the
   bar paints) so a previously-dismissed bar never flashes on load. */
:root.dt-notif-dismissed .dt-notification-bar {
    display: none;
}
/* Close (×) button — absolutely positioned so the centred text is unaffected. */
.dt-notification-bar__close {
    position: absolute;
    right: 16px;
    top: 50%;
    transform: translateY(-50%);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    padding: 0;
    border: 0;
    background: none;
    color: var(--dt-white);
    cursor: pointer;
    opacity: 0.8;
    transition: opacity 0.15s ease;
    -webkit-appearance: none;
    appearance: none;
}
.dt-notification-bar__close:hover,
.dt-notification-bar__close:focus-visible {
    opacity: 1;
}
.dt-notification-bar__close:focus-visible {
    outline: 2px solid var(--dt-white);
    outline-offset: 2px;
}
.dt-notification-bar__close svg {
    display: block;
}
.dt-notification-bar--black {
    background: var(--dt-black);
}
.dt-notification-bar--dark-green {
    background: var(--dt-dark-green);
}
.dt-notification-bar--olive {
    background: var(--dt-green);
}
.dt-notification-bar__text {
    font-family: var(--dt-font-mono);
    font-weight: 300;
    font-size: 12px;
    line-height: 1;
    color: var(--dt-white);
}
/* Specificity must beat Elementor's `.elementor a { text-decoration: none }`. */
.dt-notification-bar .dt-notification-bar__text a {
    color: inherit;
    text-decoration: underline;
    text-underline-offset: 2px;
    transition: opacity 0.15s ease;
}
.dt-notification-bar .dt-notification-bar__text a:hover,
.dt-notification-bar .dt-notification-bar__text a:focus {
    opacity: 0.75;
}

/* Main Nav: logo centered, left/right link groups, 113px tall.
   Transparent background — the parent Theme-Builder section provides bg
   (dark on inner pages, transparent over the hero on the Homepage). */
.dt-main-nav {
    display: flex;
    align-items: center;
    justify-content: space-between;
    width: 100%;
    height: 90px;
    padding: 0 88px;
    gap: 32px;
    background: transparent;
}
.dt-main-nav__group {
    display: flex;
    align-items: center;
    gap: 40px;
    margin: 0;
    padding: 0;
    list-style: none;
    flex: 1;
}
.dt-main-nav__group--left {
    justify-content: flex-start;
}
.dt-main-nav__group--right {
    justify-content: flex-end;
}
.dt-main-nav__group a {
    font-family: var(--dt-font-display);
    font-weight: 700;
    font-size: 14px;
    letter-spacing: 0.04em;
    color: var(--dt-white);
    text-decoration: none;
    text-transform: uppercase; /* defensive — defaults are already UPPERCASE */
}
.dt-main-nav__logo img {
    display: block;
    width: 119.43px;
    height: 45px;
}
/* The Homepage hero carries its own large center logo, so the header logo is
   hidden there (per design). `visibility` keeps the center column's box so the
   left/right nav groups stay positioned identically across every page. Scoped to
   the `.dt-page--home` swap container, not `body.home` — see the header-overlap
   block above for why (body class is a moving target during a Swup transition). */
.dt-page--home .dt-main-nav__logo {
    visibility: hidden;
}

/* Site Footer.
   The curline is rendered as a real <img> sitting on top of the dark body
   (not a background) — its full-width wave fills the top strip, and the
   transparent area above the wave lets the page color show through.
   The footer is full-width by virtue of the .elementor-widget-dt-site-footer
   100vw override above. */
.dt-site-footer {
    position: relative;
    width: 100%;
    color: var(--dt-white);
    font-family: var(--dt-font-mono);
    /* Footer color in one place: both the body and the curline wave read from
       this. Defaults to dark; the Menu page overrides it to olive (below). */
    --dt-footer-bg: var(--dt-dark-green);
}
/* Curline wave: the source PNG is a solid shape on transparency, so we use it
   as a mask and fill it with the footer color. That way the wave always
   matches the footer body, whatever color the page sets. aspect-ratio keeps
   the wave's proportions; the -1px bottom margin avoids a sub-pixel seam. */
.dt-site-footer__curline {
    display: block;
    width: 100%;
    aspect-ratio: 2880 / 163;
    margin-bottom: -1px;
    background-color: var(--dt-footer-bg);
    -webkit-mask: var(--dt-curline-src) no-repeat center / 100% 100%;
    mask: var(--dt-curline-src) no-repeat center / 100% 100%;
}
/* The opaque body — sits flush below the curline. */
.dt-site-footer__body {
    padding: 80px 88px 40px;
    background: var(--dt-footer-bg);
}

/* Page background extends behind the footer overlap area so the
   transparent zone above the curline doesn't show the browser white.
   The Elementor Theme-Builder footer template overhangs upward (see the
   negative margin-top below); whatever sits behind it must match the
   page color the user is on. */
body.home,
body.page-id-32 {
    background: var(--dt-green); /* Homepage = olive */
}
body.page-template-locations,
body.page-locations {
    background: var(--dt-slate); /* Locations page = slate */
}
body.page-template-shop,
body.page-products,
body.page-template-products,
body.page-shop {
    background: var(--dt-rust); /* Products page = rust */
}
body.page-template-menu,
body.page-menu {
    background: var(--dt-dark-green); /* Menu page = dark */
}
body.page-rewards,
body.page-template-rewards {
    background: var(--dt-green); /* Rewards page = olive */
}
body.page-template-gift-cards,
body.page-gift-cards {
    background: var(--dt-slate); /* Gift Cards page = slate */
}
body.page-template-privacy,
body.page-privacy,
body.page-id-38 {
    background: var(--dt-rust); /* Privacy page = rust */
}
.dt-site-footer__row {
    display: grid;
    gap: 40px;
}
.dt-site-footer__row--main {
    grid-template-columns: minmax(220px, 1fr) minmax(180px, 1fr) minmax(
            300px,
            2fr
        ) auto;
    align-items: start; /* top-align columns so the Contact Us & Subscribe headings line up */
}
.dt-site-footer__row--meta {
    margin-top: 60px;
    padding-top: 24px;
    border-top: 1px solid rgba(255, 255, 255, 0.3);
    grid-template-columns: auto 1fr;
    align-items: center;
}
/* Brand column: logo + socials, both horizontally centered. */
.dt-site-footer__col--brand {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
}
.dt-site-footer__logo {
    display: inline-block;
}
.dt-site-footer__logo img {
    width: 190px;
    height: auto;
    display: block;
}
.dt-site-footer__socials {
    display: flex;
    justify-content: center;
    gap: 13px;
    margin: 24px 0 0;
    padding: 0;
    list-style: none;
}
.dt-site-footer__socials img {
    width: 30px;
    height: 30px;
    display: block;
}
.dt-site-footer__socials a {
    display: block;
    transition: opacity 0.2s ease;
}
.dt-site-footer__socials a:hover {
    opacity: 0.7;
}
.dt-site-footer__heading {
    margin: 0 0 16px;
    font-family: var(--dt-font-display);
    font-weight: 500;
    font-size: 24px;
    line-height: 1.2;
    color: var(--dt-white);
}
.dt-site-footer__body-text {
    margin: 0;
    font-family: var(--dt-font-mono);
    font-weight: 300;
    font-size: 14px;
    line-height: 1.5;
    color: var(--dt-white);
}
/* Contact column: 4 stacked rows (email, phone, link, link) matching the
   figma body text — Roboto Mono Light 14px white, line-height 1.5, no bullets. */
.dt-site-footer__contact-list {
    margin: 0;
    padding: 0;
    list-style: none;
}
/* Separate the contact details (email/phone) from the links below them. */
.dt-site-footer__contact-row--gap {
    margin-top: 26px;
}
.dt-site-footer__contact-link {
    font-family: var(--dt-font-mono);
    font-weight: 300;
    font-size: 14px;
    line-height: 1.5;
    color: var(--dt-white);
    text-decoration: none;
    transition: opacity 0.15s ease;
}
.dt-site-footer__contact-link:hover,
.dt-site-footer__contact-link:focus {
    text-decoration: underline;
    color: var(--dt-white);
}
/* Back-to-top widget: a 51×49 PNG pinned to the bottom-right of the viewport.
   It is `position: fixed` (lifted out of the footer flow), hidden until the page
   is scrolled a little — assets/back-to-top.js toggles `.is-visible`. While
   scrolling it floats at bottom:50px; over the last stretch of the page the
   script sets `bottom` scroll-linked so the cup "sticks" to a point ~210px above
   the page bottom and scrolls up with the footer instead of overlapping it. The
   `bottom` is driven per-frame in JS, so it is intentionally NOT transitioned. */
.dt-site-footer__top {
    position: fixed;
    right: 50px;
    bottom: 50px;
    z-index: 90; /* above page content; header/notification bar top out at 20 */
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 51px;
    height: 49px;
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 0.25s ease, visibility 0.25s ease;
}
.dt-site-footer__top.is-visible {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
}
.dt-site-footer__top img {
    width: 51px;
    height: 49px;
    object-fit: contain;
    display: block;
}
/* Payment icons: exact 37×23 with a small radius to harmonise rounded vs
   square source PNGs (Visa/Mastercard ship square; AmEx/Apple Pay rounded). */
.dt-site-footer__payments {
    display: flex;
    gap: 7px;
    margin: 0;
    padding: 0;
    list-style: none;
}
.dt-site-footer__payments li {
    display: flex;
}
.dt-site-footer__payments img {
    width: 37px;
    height: 23px;
    object-fit: cover;
    /* !important: an upstream img reset (Elementor/GF) was zeroing this out. */
    border-radius: 4px !important;
    display: block;
}
.dt-site-footer__disclaimer {
    margin: 0;
    text-align: right;
    font-family: var(--dt-font-mono);
    font-weight: 300;
    font-style: italic;
    font-size: 13px;
    line-height: 1.5;
    color: var(--dt-white);
}

/* Footer Gravity Form — match Figma: single underlined input row with
   "Your Email" on the left and SUBSCRIBE label aligned to the right side
   of the same underline. We achieve the layout by:
   1. Hiding First/Last fields (only Email shows).
   2. Floating the gform_footer (submit button) inline + right.
   3. Removing the GF default visual chrome on the input + button. */
.dt-site-footer__form .gform_wrapper,
.dt-site-footer__form .gform_wrapper form,
.dt-site-footer__form .gform_wrapper .gform_body {
    position: relative;
}
.dt-site-footer__form .gform_wrapper .gform_fields {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0;
}
.dt-site-footer__form .gform_wrapper .gfield.dt-nl-first,
.dt-site-footer__form .gform_wrapper .gfield.dt-nl-last {
    display: none;
}
.dt-site-footer__form .gform_wrapper .gfield label,
.dt-site-footer__form .gform_wrapper .gfield_label,
.dt-site-footer__form .gform_wrapper .gfield_description {
    display: none;
}
.dt-site-footer__form .gform_wrapper input[type="email"],
.dt-site-footer__form .gform_wrapper input[type="text"] {
    background: transparent !important;
    border: 0 !important;
    border-bottom: 1px solid var(--dt-white) !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    padding: 6px 110px 6px 0 !important; /* room on the right for SUBSCRIBE */
    color: var(--dt-white) !important;
    font-family: var(--dt-font-mono) !important;
    font-weight: 300 !important;
    font-size: 16px !important;
    width: 100% !important;
    outline: none !important;
    text-align: left !important;
}
.dt-site-footer__form .gform_wrapper input::placeholder {
    color: rgba(255, 255, 255, 0.85);
    font-family: var(--dt-font-mono);
    font-weight: 300;
}
/* Submit ("SUBSCRIBE") absolutely positioned to the right of the input row.
   Stretched top-to-bottom over the input and flex-centered so the label's
   text aligns vertically with the "Your Email" placeholder. */
.dt-site-footer__form .gform_wrapper .gform_footer {
    position: absolute !important;
    top: 0;
    bottom: 0;
    right: 0;
    display: flex;
    align-items: center;
    padding: 0 !important;
    margin: 0 !important;
    z-index: 2;
}
.dt-site-footer__form .gform_wrapper .gform_footer input[type="submit"],
.dt-site-footer__form .gform_wrapper .gform_footer button {
    background: transparent !important;
    border: 0 !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    color: var(--dt-white) !important;
    font-family: var(--dt-font-display) !important;
    font-weight: 700 !important;
    font-size: 16px !important;
    letter-spacing: 0.04em !important;
    text-transform: uppercase;
    cursor: pointer !important;
    padding: 0 !important;
    min-width: 0 !important;
    text-shadow: none !important;
    transition: opacity 0.2s ease;
}
.dt-site-footer__form .gform_wrapper .gform_footer input[type="submit"]:hover,
.dt-site-footer__form .gform_wrapper .gform_footer button:hover {
    opacity: 0.7 !important;
}
/* Hide any AJAX spinner so it doesn't disturb the inline layout. */
.dt-site-footer__form .gform_ajax_spinner {
    display: none !important;
}

/* Static fallback used when GF isn't available — mirrors the real form. */
.dt-site-footer__form-fallback {
    display: flex;
    align-items: center;
    gap: 16px;
}
.dt-site-footer__form-fallback input[type="email"] {
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--dt-white);
    border-radius: 0;
    padding: 6px 0;
    color: var(--dt-white);
    font-family: var(--dt-font-mono);
    font-weight: 300;
    font-size: 16px;
    flex: 1;
    min-width: 0;
    text-align: left;
}
.dt-site-footer__form-fallback input::placeholder {
    color: rgba(255, 255, 255, 0.9);
}
.dt-site-footer__form-fallback button {
    background: transparent;
    border: 0;
    color: var(--dt-white);
    font-family: var(--dt-font-display);
    font-weight: 700;
    font-size: 16px;
    letter-spacing: 0.04em;
    cursor: pointer;
    padding: 0;
    transition: opacity 0.2s ease;
}
.dt-site-footer__form-fallback button:hover {
    opacity: 0.7;
}

/* Hero: full-bleed photo + scrim, centered logo, lower-left headline + eyebrow. */
.dt-hero {
    position: relative;
    width: 100%;
    min-height: 1024px;
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    color: var(--dt-white);
    padding: 60px 108px;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    gap: 32px;
}
.dt-hero__video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: 0; /* sits below the .dt-scrim::after overlay and content */
}
.dt-hero__logo {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 357px;
    max-width: 50%;
}
.dt-hero__logo img {
    width: 100%;
    height: auto;
    display: block;
}
.dt-hero__headline {
    margin: 0;
    font-family: var(--dt-font-display);
    font-weight: 500;
    font-size: var(--dt-h2-size);
    line-height: 1.15;
    color: var(--dt-white);
    white-space: pre-line; /* preserve textarea line breaks */
}
.dt-hero__eyebrow {
    display: flex;
    align-items: center;
    gap: 16px;
    font-family: var(--dt-font-mono);
    font-weight: 700;
    font-size: var(--dt-eyebrow-size);
    color: var(--dt-white);
    /* Rendered as a <button> (scrolls to the first section) — strip the
       native button chrome so it looks identical to the original text. */
    appearance: none;
    -webkit-appearance: none;
    margin: 0;
    padding: 0;
    background: none;
    border: 0;
    text-align: inherit;
    line-height: inherit;
    letter-spacing: inherit;
    cursor: pointer;
}
.dt-hero__eyebrow:focus-visible {
    outline: 2px solid var(--dt-white);
    outline-offset: 4px;
}
.dt-hero__arrow {
    display: block;
}

/* Two Column Intro: image one side, text content the other.
   Outer padding is controlled by an Elementor DIMENSIONS control
   (rendered via inline `padding:` style on .dt-two-col). */
.dt-two-col {
    display: grid;
    grid-template-columns: 686fr 754fr;
    align-items: center;
    gap: 80px;
    color: var(--dt-white);
    padding: 80px 100px; /* default — overridden by inline style from widget */
}
.dt-two-col--image-right {
    grid-template-columns: 754fr 686fr;
}
.dt-two-col--image-right .dt-two-col__image-wrap {
    order: 2;
}
.dt-two-col--image-right .dt-two-col__content {
    order: 1;
    padding-left: 0;
    padding-right: 0;
}
/* Wrapper holds the image PLUS the decoration as a sibling so the
   decoration is NOT clipped by the image's rounded-right overflow:hidden. */
.dt-two-col__image-wrap {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
}
.dt-two-col__image {
    width: 100%;
    border-radius: var(--dt-radius); /* all four corners */
    overflow: hidden; /* clip the image (and stacked carousel slides) to the radius */
}
.dt-two-col__image img {
    width: 100%;
    height: auto;
    display: block;
}
/* Featured-products carousel: stack slides, crossfade the active one.
   First <img> stays in normal flow as the height sizer; the rest overlay it.
   The first child being opacity:0 when inactive still holds layout height
   (opacity doesn't remove from flow), so during a crossfade between two later
   slides nothing bleeds through. Crossfade is fixed at 0.8s; only the hold
   interval is editable (read from data-dt-carousel-interval in JS). */
.dt-two-col__image--carousel {
    position: relative;
}
.dt-two-col__image--carousel img {
    transition: opacity .8s ease;
}
.dt-two-col__image--carousel img:not(:first-child) {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.dt-two-col__image--carousel img:not(.is-active) {
    opacity: 0;
}
.dt-two-col__image--carousel img.is-active {
    opacity: 1;
}
/* Decoration (e.g. wine bottle illustration above the Featured Products image).
   The X/Y offset sliders feed the --dt-deco-x / --dt-deco-y custom properties
   so both anchor modes below can reuse the same controls. */
.dt-two-col__decoration {
    position: absolute;
    z-index: 2;
    pointer-events: none;
}
/* "Above" anchor (default): floats over the top edge, horizontally centered.
   Negative Y lifts it above the image; the X slider shifts it left/right. */
.dt-two-col__decoration--above {
    top: var(--dt-deco-y, -80px);
    left: 50%;
    transform: translateX(calc(-50% + var(--dt-deco-x, 0px)));
}
/* "Bottom-right" anchor: pinned to the image's bottom-right corner. Positive
   X/Y inset it toward the image center; negative values push it outward. */
.dt-two-col__decoration--bottom-right {
    right: var(--dt-deco-x, 0px);
    bottom: var(--dt-deco-y, 0px);
}
.dt-two-col__decoration img {
    display: block;
    max-width: 220px; /* default — overridden via the widget's max-width slider */
    width: auto;
    height: auto;
}
.dt-two-col__content {
    /* No inner side padding — the 80px column gap on .dt-two-col is the only
	   gap between the image and the text. */
    padding-left: 0;
    padding-right: 0;
    max-width: 600px;
}
.dt-two-col__heading {
    margin: 0 0 32px;
    font-family: var(--dt-font-display);
    font-weight: 400;
    font-size: var(--dt-h1-size);
    line-height: var(--dt-h1-lh);
    color: var(--dt-white);
    white-space: pre-line;
}
.dt-two-col__tagline {
    margin: 0 0 24px;
    font-family: var(--dt-font-display);
    font-weight: 700;
    font-size: var(--dt-tagline-size);
    line-height: var(--dt-tagline-lh);
    letter-spacing: var(--dt-tagline-track);
    color: var(--dt-white);
    white-space: pre-line;
}
.dt-two-col__body {
    margin: 0 0 32px;
    font-family: var(--dt-font-mono);
    font-weight: 300;
    font-size: var(--dt-body-size);
    line-height: var(--dt-body-lh);
    color: var(--dt-white);
}

/* Rewards Hero: left photo (flush-left, rounded right) + right text column with
   headline / tagline / intro + benefits / SIGN UP / coffee-mug rating / quote.
   Figma 1440: image x=-3 w=663, content x=739 w=597, 79px gutter, ~104px right inset. */
.dt-rewards-hero {
    display: flex;
    align-items: flex-start;
    gap: 79px;
    padding: 60px 104px 80px 0; /* image flush to the left edge; nav-to-hero top gap */
    color: var(--dt-white);
}
.dt-rewards-hero__image {
    flex: 0 1 50%; /* scales to ~half the screen like the Simple Sip section */
    max-width: 50%;
}
.dt-rewards-hero__image img {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 663 / 482; /* preserve the designed crop while the box scales */
    object-fit: cover;
}
.dt-rewards-hero__content {
    flex: 1 1 auto;
    max-width: 597px;
}
.dt-rewards-hero__heading {
    margin: 0 0 18px;
    font-family: var(--dt-font-display);
    font-weight: 400;
    font-size: var(--dt-h1-size);
    line-height: var(--dt-h1-lh);
    color: var(--dt-white);
    white-space: pre-line;
}
.dt-rewards-hero__tagline {
    margin: 0 0 22px;
    font-family: var(--dt-font-display);
    font-weight: 700;
    font-size: var(--dt-tagline-size);
    line-height: var(--dt-tagline-lh);
    letter-spacing: var(--dt-tagline-track);
    text-transform: uppercase;
    color: var(--dt-white);
}
.dt-rewards-hero__intro {
    margin: 0 0 4px;
    font-family: var(--dt-font-mono);
    font-weight: 300;
    font-size: var(--dt-body-size);
    line-height: var(--dt-body-lh);
    color: var(--dt-white);
}
.dt-rewards-hero__benefits {
    margin: 0 0 40px;
    padding-left: 1.25em;
    list-style: disc;
    font-family: var(--dt-font-mono);
    font-weight: 300;
    font-size: var(--dt-body-size);
    line-height: var(--dt-body-lh);
    color: var(--dt-white);
}
.dt-rewards-hero__benefits li {
    margin: 0;
}
.dt-rewards-hero__cta {
    margin-bottom: 60px;
}
.dt-rewards-hero__cta .dt-arrow-link {
    font-family: var(--dt-font-mono);
    font-weight: 400;
    font-size: 18px;
}
.dt-rewards-hero__mugs {
    display: flex;
    align-items: center;
    gap: 18px;
    margin-bottom: 56px;
}
.dt-rewards-hero__mug {
    display: inline-flex;
    width: 47px;
    height: 45px;
    color: #6b5847; /* "empty" mug color — shown when the glow animation is off */
}
.dt-rewards-hero__mug--gold {
    color: var(--dt-gold); /* the last N mugs */
}
.dt-rewards-hero__mug-icon {
    display: block;
    width: 100%;
    height: 100%;
}

/* Animated "fill" glow: cups light up 1→5 (each stays lit while the next comes
   on), then unwind 5→1, landing back on zero exactly where the loop restarts so
   there's no jump. Cup 1 has the widest lit window; cup 5 lights only briefly at
   the peak when all five are gold. */
.dt-rewards-hero__mug:nth-child(1) .dt-rewards-hero__mug-icon { animation: dt-mug-glow-1 7s ease-in-out infinite; }
.dt-rewards-hero__mug:nth-child(2) .dt-rewards-hero__mug-icon { animation: dt-mug-glow-2 7s ease-in-out infinite; }
.dt-rewards-hero__mug:nth-child(3) .dt-rewards-hero__mug-icon { animation: dt-mug-glow-3 7s ease-in-out infinite; }
.dt-rewards-hero__mug:nth-child(4) .dt-rewards-hero__mug-icon { animation: dt-mug-glow-4 7s ease-in-out infinite; }
.dt-rewards-hero__mug:nth-child(5) .dt-rewards-hero__mug-icon { animation: dt-mug-glow-5 7s ease-in-out infinite; }

@keyframes dt-mug-glow-1 {
    0%, 5%    { color: #ffffff; }
    8%, 95%   { color: rgb(235, 178, 53); }
    98%, 100% { color: #ffffff; }
}
@keyframes dt-mug-glow-2 {
    0%, 15%   { color: #ffffff; }
    18%, 85%  { color: rgb(235, 178, 53); }
    88%, 100% { color: #ffffff; }
}
@keyframes dt-mug-glow-3 {
    0%, 25%   { color: #ffffff; }
    28%, 75%  { color: rgb(235, 178, 53); }
    78%, 100% { color: #ffffff; }
}
@keyframes dt-mug-glow-4 {
    0%, 35%   { color: #ffffff; }
    38%, 65%  { color: rgb(235, 178, 53); }
    68%, 100% { color: #ffffff; }
}
@keyframes dt-mug-glow-5 {
    0%, 45%   { color: #ffffff; }
    48%, 55%  { color: rgb(235, 178, 53); }
    58%, 100% { color: #ffffff; }
}
.dt-rewards-hero__quote {
    margin: 0 0 0 auto; /* right-aligned within the content column */
    max-width: 565px;
    font-family: var(--dt-font-script);
    font-weight: 400;
    font-size: 20px;
    line-height: 40px;
    color: var(--dt-white);
    opacity: 0.2;
    text-align: right;
}
@media (max-width: 1024px) {
    .dt-rewards-hero {
        flex-direction: column;
        gap: 40px;
        padding: 40px 24px;
    }
    .dt-rewards-hero__content {
        flex: none;
        width: 100%;
        max-width: 100%;
    }
    /* Image sticks to the left screen edge (client review): bleed past the 24px
       hero gutter. The wrapper already rounds the right corners + clips. */
    .dt-rewards-hero__image {
        flex: none;
        width: calc(100% + 24px);
        max-width: none;
        margin-left: -24px;
    }
    .dt-rewards-hero__quote {
        margin-left: 0;
        text-align: left;
    }
}

/* Gift Cards Hero: left photo (flush-left, rounded right) + right text column
   with headline / tagline / body / "Buy Gift Cards" arrow-link / brand marks.
   Figma 1440: image x=1 w=658 h=479, content x=740 w=593, ~81px gutter. */
.dt-gift-cards-hero {
    display: flex;
    align-items: flex-start;
    gap: 81px;
    /* Bottom padding clears the footer's curved wave (.dt-site-footer__curline),
       which tucks up 120px via the footer's margin-top:-120px. Since the image is
       the tallest element here, 150px keeps it above the wave with a small gap. */
    padding: 60px 100px 150px 0; /* image flush to the left edge; nav-to-hero top gap */
    color: var(--dt-white);
}
.dt-gift-cards-hero__image {
    flex: 0 1 50%; /* scales to ~half the screen like the Simple Sip section */
    max-width: 50%;
}
.dt-gift-cards-hero__image img {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 658 / 479; /* preserve the designed crop while the box scales */
    object-fit: cover;
}
.dt-gift-cards-hero__content {
    flex: 1 1 auto;
    max-width: 593px;
}
.dt-gift-cards-hero__heading {
    margin: 0 0 32px;
    font-family: var(--dt-font-display);
    font-weight: 400;
    font-size: var(--dt-h1-size);
    line-height: var(--dt-h1-lh);
    color: var(--dt-white);
    white-space: pre-line;
}
.dt-gift-cards-hero__tagline {
    margin: 0 0 22px;
    font-family: var(--dt-font-display);
    font-weight: 700;
    font-size: var(--dt-tagline-size);
    line-height: var(--dt-tagline-lh);
    letter-spacing: var(--dt-tagline-track);
    text-transform: uppercase;
    color: var(--dt-white);
}
.dt-gift-cards-hero__body {
    margin: 0 0 28px;
    max-width: 593px;
    font-family: var(--dt-font-mono);
    font-weight: 300;
    font-size: var(--dt-body-size);
    line-height: var(--dt-body-lh);
    color: var(--dt-white);
}
.dt-gift-cards-hero__cta {
    margin-bottom: 60px;
}
.dt-gift-cards-hero__cta .dt-arrow-link {
    font-family: var(--dt-font-mono);
    font-weight: 400;
    font-size: 18px;
    text-transform: uppercase;
}
.dt-gift-cards-hero__marks {
    display: flex;
    align-items: center;
    gap: 8px;
}
.dt-gift-cards-hero__marks img {
    display: block;
    width: 59.56px;
    height: 37.28px;
}
/* Client override carried over from the Customizer. Note: the marks container
   is display:flex (above), which blockifies its children, so this is a no-op in
   practice — kept for parity with the client's intent and safe to drop. */
.page-gift-cards .dt-gift-cards-hero__marks img {
    display: inline-block;
}
@media (max-width: 1024px) {
    .dt-gift-cards-hero {
        flex-direction: column;
        gap: 40px;
        padding: 40px 24px 150px;
    }
    .dt-gift-cards-hero__content {
        flex: none;
        width: 100%;
        max-width: 100%;
    }
    /* Image sticks to the left screen edge (matches the Rewards hero): bleed past
       the 24px hero gutter. The wrapper already rounds the right corners + clips. */
    .dt-gift-cards-hero__image {
        flex: none;
        width: calc(100% + 24px);
        max-width: none;
        margin-left: -24px;
    }
}

/* Location Card: 400×605 — banner + pill + title + body + 2 links. */
.dt-location-card {
    position: relative;
    width: 400px;
    max-width: 100%;
    color: var(--dt-white);
    font-family: var(--dt-font-mono);
}
.dt-location-card__banner {
    margin-bottom: 24px;
}
.dt-location-card__banner img {
    width: 100%;
    height: 261px;
    object-fit: cover;
    display: block;
}
.dt-location-card__pill {
    position: absolute;
    top: 16px;
    left: 0;
    z-index: 2;
}
/* Title row: title on the left, decoration icons aligned with it on the right. */
.dt-location-card__title-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 8px;
}
.dt-location-card__title {
    margin: 0;
    font-family: var(--dt-font-display);
    font-weight: 700;
    font-size: 20px;
    letter-spacing: 0.04em;
    color: var(--dt-white);
}
/* Decoration icons (coffee cup, wine bottle, location pin, phone…) sit to the
   right of the title, vertically centered against it. */
.dt-location-card__decorations {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-left: auto;
    padding-right: 10px;
    flex-shrink: 0;
}
.dt-location-card__decorations img {
    display: block;
    width: 22px;
    height: auto;
    object-fit: contain;
}
.dt-location-card__info {
    margin-bottom: 24px;
    font-weight: 300;
    font-size: var(--dt-body-size);
    line-height: var(--dt-body-lh);
}
.dt-location-card__address {
    margin: 0 0 16px;
}
.dt-location-card__hours-heading {
    margin: 0 0 4px;
    font-family: var(--dt-font-display);
    font-weight: 700;
    font-size: 16px;
    letter-spacing: 0.04em;
    color: var(--dt-white);
}
.dt-location-card__hours {
    margin: 0;
}
.dt-location-card__actions {
    display: flex;
    flex-direction: column;
    gap: 12px;
}
.dt-location-card__actions .dt-arrow-link {
    font-size: 20px;
}

/* Instagram Tile: square image + caption. */
.dt-ig-tile {
    display: block;
    color: var(--dt-white);
    text-decoration: none;
    font-family: var(--dt-font-mono);
}
/* Scoped under .dt-ig-tile so the radius beats Elementor's `.elementor img
   { border-radius: 0 }` reset (which otherwise out-specifies a bare class). */
.dt-ig-tile .dt-ig-tile__image {
    display: block;
    width: 100%;
    aspect-ratio: 1 / 1;
    object-fit: cover;
    border-radius: var(--dt-radius); /* 15px — live feed photos are square, round in CSS */
}
.dt-ig-tile__caption {
    margin: 16px 0 0;
    font-weight: 300;
    font-size: var(--dt-body-size);
    line-height: var(--dt-body-lh);
    /* Captions can be long — cap at 3 lines (Figma §1 Section 6) with an ellipsis. */
    display: -webkit-box;
    -webkit-line-clamp: 3;
    line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Instagram Feed (Dynamic): 1 row × 5 columns, ~22px gap (Figma §1 Section 6).
   Tiles are direct grid children, captions sit below each image. The columns
   are fluid (1fr) so the tiles grow a little on wide screens — capped by the
   grid's max-width — and stay at the 232px design size on the 1248px canvas.
   Collapses to 3 / 2 columns on smaller screens. */
.dt-ig-grid {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    column-gap: 22px;
    row-gap: 40px;
    justify-content: center;
    align-items: start;
    max-width: 1488px;
    margin-left: auto;
    margin-right: auto;
}
/* The feed sits in a boxed Elementor container whose inner wrapper caps content
   at the kit's content width (~1140px) — narrower than the grid's 1488px max,
   so without this the tiles can't grow and big side gutters appear. Widen just
   the container that holds this widget so the row of 5 can expand on large
   screens. Scoped via :has() so no other boxed section is affected. */
.e-con-boxed:has(.elementor-widget-dt-instagram-feed) > .e-con-inner {
    max-width: 1488px;
}

@media (max-width: 1023px) {
    .dt-ig-grid {
        grid-template-columns: repeat(3, minmax(0, 232px));
    }
}
/* Homepage "Follow Us": expand the Instagram tiles to the Section Heading band.
   Same treatment as Our Locations — the grid's centered max-width cap (1488px,
   plus the boxed container's matching cap) let the heading grow wider than the
   tile row on large screens, leaving the first/last tile inset from the heading.
   Drop the caps so the row fills the heading's container and the tiles stretch,
   keeping the first/last tile flush with the heading's edges at every width.
   Scoped via :has() to the feed that shares a container with a Section Heading. */
.e-con:has(> .elementor-widget-dt-section-heading) .e-con-boxed:has(.elementor-widget-dt-instagram-feed) > .e-con-inner {
    max-width: none;
}
.e-con:has(> .elementor-widget-dt-section-heading) .dt-ig-grid {
    max-width: none;
}
@media (max-width: 1023px) {
    .e-con:has(> .elementor-widget-dt-section-heading) .dt-ig-grid {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}
/* Mobile (Figma 184:245): horizontal scroll — tiles in a single row, ~2 tiles
   visible with the next peeking in. The section heading's "Follow Us" link is
   hidden on mobile; a duplicate appears below the scroll row in the feed widget.
   The widget is extended by negative margins to break out of the section's 25px
   side padding so tiles can scroll flush to the viewport edges. A matching
   padding-left restores the leading indent for the first tile and the follow link. */
@media (max-width: 768px) {
    /* Allow the grid (and follow link) to visually escape the widget box. */
    .elementor-widget-dt-instagram-feed {
        overflow: visible;
    }
    .dt-ig-grid,
    .e-con:has(> .elementor-widget-dt-section-heading) .dt-ig-grid {
        display: flex;
        flex-wrap: nowrap;
        justify-content: flex-start; /* override desktop center; centering shifts overflowing tiles off-screen */
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        column-gap: 22px;
        row-gap: 0;
        max-width: none;
        /* Break out of the section's 25px side padding so tiles reach the viewport
           edges, then restore the leading indent for the first tile. */
        width: 100vw;
        margin-left: -25px;
        padding-left: 25px;
        padding-bottom: 4px; /* breathing room above scrollbar on browsers that show it */
    }
    .dt-ig-grid::-webkit-scrollbar {
        display: none;
    }
    .dt-ig-grid .dt-ig-tile {
        flex: 0 0 232px;
    }
    /* Trailing right spacer — padding-right on an overflow flex container is
       unreliable cross-browser, so use a pseudo-element as the last flex child. */
    .dt-ig-grid::after {
        content: '';
        flex: 0 0 25px;
    }
}

/* "Follow Us" footer link shown only on mobile (below the scroll row). Hidden on
   desktop because it lives in the section heading's right-link slot there. */
.dt-ig-follow {
    display: none;
}
@media (max-width: 768px) {
    .dt-ig-follow {
        display: block;
        margin-top: 28px;
    }
    .dt-ig-follow .dt-arrow-link__text {
        text-transform: uppercase;
    }
}

/* =========================================================================
   Menu page widgets — Subnav, Section (left decoration), Category (table).
   Reference: docs/figma-screens.md §4. All values are the verified Figma
   numbers (1440 canvas). The Category grid is identical across every
   category so the S/M/L · GL/BTL · single price columns line up across the
   whole page.
   ========================================================================= */

/* The global notification bar reads olive on the Menu page (it's dark-green
   elsewhere). Page-scoped override of the Theme-Builder header widget. */
body.page-menu .dt-notification-bar {
    background: var(--dt-green) !important;
}

/* Let the Menu Section photo sit flush to its container's left edge. */
.elementor-widget-dt-menu-section > .elementor-widget-container {
    padding: 0 !important;
}

/* ---- Menu Subnav ---- */
/* 520px-wide row, horizontally centered → starts at x=460 on the 1440 canvas.
   Roboto Mono 20 white, 44px gaps, active item underlined in slate. */
.dt-menu-subnav {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 44px;
    padding: 32px 0;
}
.dt-menu-subnav__item {
    position: relative;
    font-family: var(--dt-font-mono);
    font-weight: 400;
    font-size: 20px;
    line-height: 1;
    color: var(--dt-white);
    text-decoration: none;
    white-space: nowrap;
    text-transform: uppercase;
}
/* Active item: a hand-drawn squiggle (Figma "Vector 10"), not a flat underline.
   Centered just below the label. The squiggle is drawn with a CSS mask so its
   colour follows --dt-subnav-underline — the shipped SVG is slate, which is
   invisible on the slate Locations background, so colour is driven here. */
.dt-menu-subnav__item--active::after {
    content: "";
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    bottom: -12px;
    width: 73px;
    height: 10px;
    background-color: var(--dt-subnav-underline, #9cb6be);
    -webkit-mask: url(assets/subnav-active.svg) no-repeat center / contain;
    mask: url(assets/subnav-active.svg) no-repeat center / contain;
}
/* The Locations page sits on slate, and the Shop page on rust, so the
   underline reads white on both (per Figma). */
body.page-locations,
body.page-shop {
    --dt-subnav-underline: #ffffff;
}

/* ---- Menu Section (left decoration column) ---- */
/* Photo top (495×350, rounded right), decorative squiggle bleeding off the
   left border, and the big H1 heading pinned to the bottom-left at x=100.
   The decoration stretches to the full height of the section (see the
   absolute-positioning layout block further down) so the heading sits at the
   bottom, level with the last price row. */
.dt-menu-section,
.dt-menu-section > .elementor-widget-container {
    height: 100%;
}
.dt-menu-section__deco {
    position: relative;
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 350px;
    color: var(--dt-white);
}
/* The frame drives the photo's size: it fills the cell width (keeping the
   design's 68px breathing gap before the tables) and holds the 495×350 aspect
   ratio as it widens, so the photo scales up instead of cropping into an
   ever-wider panorama. The squiggle (below) anchors to the frame's bottom. */
.dt-menu-section__photo-frame {
    position: relative;
    width: calc(100% - 68px);
    aspect-ratio: 495 / 350;
    /* Cap the height so the photo can never grow tall enough to push the
       squiggle — anchored to its bottom — down onto the section title. The 100%
       resolves to the deco cell height (= the price-table height of that
       chapter), so short chapters (Food) cap sooner than tall ones (Wine); past
       the cap the photo grows wider-only, an accepted approximation. min()/max()
       keep an absolute 560px ceiling and a 300px floor so it never collapses. */
    max-height: min(560px, max(300px, calc(100% - 460px)));
}
.dt-menu-section__photo {
    width: 100%;
    height: 100%;
}
.dt-menu-section__photo img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.dt-menu-section__squiggle {
    position: absolute;
    left: 0; /* bleeds off the container's left border, per the design */
    /* Anchored 50px up from the photo's bottom-left corner. The frame
       shrink-wraps the photo, so 100% tracks the photo's height as it grows. */
    top: calc(100% - 50px);
    width: 280px;
    height: auto;
    z-index: 0;
    pointer-events: none;
}
.dt-menu-section__heading {
    position: relative;
    z-index: 1;
    margin: auto 0 0 100px; /* margin-top:auto pins the heading to the bottom */
    padding-top: 80px;
    font-family: var(--dt-font-display);
    font-weight: 400;
    font-size: var(--dt-h1-size); /* 72 */
    line-height: var(--dt-h1-lh); /* 85 */
    color: var(--dt-white);
    /* The box bottom is bottom-aligned with the last price row, but the 72/85
       heading carries ~23.5px below its baseline (descent + half-leading) vs
       ~8px on the 16/24 rows. Nudge it down by that 15.5px difference so the
       text BASELINES line up, not just the box bottoms. (text-box-trim would
       do this declaratively but lacks Firefox support.) */
    transform: translateY(15.5px);
}

/* ---- Menu Category (price table) ---- */
/* One universal grid: name | S(877) | gap | M/GL(979) | gap | L/BTL(1067).
   Track widths sum to 565px = the Figma table width. Price boxes are 61px,
   center-aligned. The name cell auto-extends across whichever left columns a
   category doesn't use (see --p* below). */
.dt-menu-category {
    width: 565px;
    max-width: 100%;
    margin: 0; /* spacing between categories comes from the column gap on the
                  right cell, so the last category ends flush with its last row
                  and the section heading can bottom-align with it */
    color: var(--dt-white);
}
.dt-menu-category__head,
.dt-menu-category__row {
    display: grid;
    grid-template-columns: 314px 61px 41px 61px 27px 61px;
    align-items: baseline;
}
.dt-menu-category__head {
    margin-bottom: 24px;
}
.dt-menu-category__label,
.dt-menu-category__col-head {
    font-family: var(--dt-font-display);
    font-weight: 700;
    font-size: 14px;
    line-height: 28px;
    letter-spacing: var(--dt-tagline-track); /* 4% */
    color: var(--dt-white);
}
.dt-menu-category__label {
    grid-column: 1;
    text-transform: uppercase; /* category names are always capitalized per the design */
}
.dt-menu-category__col-head {
    text-align: center;
}
.dt-menu-category__col-head--1 {
    grid-column: 2;
}
.dt-menu-category__col-head--2 {
    grid-column: 4;
}
.dt-menu-category__col-head--3 {
    grid-column: 6;
}
.dt-menu-category__note {
    margin: 0 0 8px;
    font-family: var(--dt-font-mono);
    font-weight: 300;
    font-style: italic;
    font-size: 14px;
    line-height: 1.5;
    color: var(--dt-white);
}
.dt-menu-category__items {
    margin: 0;
    padding: 0;
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 14px; /* ~38px single-row pitch; no trailing space after the last row */
}
.dt-menu-category__name {
    padding-right: 16px;
    font-family: var(--dt-font-mono);
    font-weight: 300;
    font-size: 16px;
    line-height: 1.5; /* 24px within an item; wrapped descriptions stay tight */
    color: var(--dt-white);
}
/* Emphasized part of an item name (Figma uses Bold for the dish/winery name
   and Light for the trailing region/description). Authored in the Name field
   by wrapping the bold span in **double asterisks**. */
.dt-menu-category__em {
    font-weight: 700;
}
.dt-menu-category__price {
    grid-row: 1; /* keep prices on the item's first line when the name wraps */
    font-family: var(--dt-font-mono);
    font-weight: 300;
    font-size: 16px;
    line-height: 1.5;
    text-align: center;
    color: var(--dt-white);
}
.dt-menu-category__price--1 {
    grid-column: 2;
}
.dt-menu-category__price--2 {
    grid-column: 4;
}
.dt-menu-category__price--3 {
    grid-column: 6;
}
/* The item-name cell stretches up to the first price column the category
   actually uses, so Coffee (S/M/L) keeps a narrow name column while Food
   (single price) gets the full width for long descriptions. */
.dt-menu-category--p1 .dt-menu-category__name {
    grid-column: 1 / 2;
}
.dt-menu-category--p2 .dt-menu-category__name {
    grid-column: 1 / 4;
}
.dt-menu-category--p3 .dt-menu-category__name {
    grid-column: 1 / 6;
}
.dt-menu-category--p0 .dt-menu-category__name {
    grid-column: 1 / -1;
}

/* ---- Section layout (Coffee / Wine / Food) ----
   A section is an outer container (A) wrapping two inner containers: a left
   cell (B) holding the Menu Section decoration, and a right cell (C) holding
   the section's Menu Category tables. We drive the whole two-column layout
   from CSS here and force the flex behaviour ourselves — Elementor's own
   container flex/width/class settings aren't applied reliably to
   programmatically-built pages. Cells are matched by :has() on the stable
   widget classes, so this holds regardless of element IDs.
       A  .e-con:has(> .e-con > .dt-menu-section)   ← row, centered at 1440
       B  .e-con:has(> .dt-menu-section)            ← 563px left cell
       C  .e-con:has(> .dt-menu-category)           ← right cell, stacked  */
.e-con:has(> .e-con > .elementor-widget-dt-menu-section) {
    display: flex !important;
    flex-direction: row !important;
    flex-wrap: nowrap !important;
    align-items: stretch !important;
    gap: 0 !important;
    width: 100%;
    max-width: var(--dt-canvas);
    margin-inline: auto !important;
    padding: 80px 0 !important;
}
/* 30%-white divider above every section after the first. */
.e-con:has(> .e-con > .elementor-widget-dt-menu-section)
    + .e-con:has(> .e-con > .elementor-widget-dt-menu-section) {
    border-top: 1px solid rgba(255, 255, 255, 0.3);
}
/* Extra room beneath the final section: the footer overlaps upward by 120px
   (its global margin-top:-120px), so without this the curline crowds the last
   rows. This lives in CSS because the section padding above is !important and
   would otherwise override a value set in the editor. */
.e-con:has(> .e-con > .elementor-widget-dt-menu-section):last-of-type {
    padding-bottom: 200px !important;
}
/* B — left decoration cell, fixed width, full height of the row. It is a flex
   column so the Menu Section widget can stretch to the row's full height,
   which lets the heading bottom-align with the last price row. */
.e-con:has(> .elementor-widget-dt-menu-section) {
    flex: 0 0 563px !important;
    align-self: stretch;
    display: flex !important;
    flex-direction: column !important;
    padding: 0 !important;
}
.e-con:has(> .elementor-widget-dt-menu-section)
    > .elementor-widget-dt-menu-section {
    flex: 1 1 auto;
}
/* C — right table cell: fills the rest, tables stacked with a gap between them
   (not trailing margins) so the last table ends flush and the heading can
   bottom-align with its last row. */
.e-con:has(> .elementor-widget-dt-menu-category) {
    flex: 1 1 auto !important;
    display: flex !important;
    flex-direction: column !important;
    align-items: flex-start !important;
    gap: 48px !important;
    padding: 0 !important;
}
.elementor-widget-dt-menu-category > .elementor-widget-container {
    padding: 0 !important;
}

/* ===================================================================
   Dynamic widgets (CPT-driven) — parallel layout rules.
   The static Menu/Locations pages composed many Elementor containers, so their
   layout is matched via :has(> .e-con > …) above. The dynamic widgets emit a
   single widget each, so that nested-container DOM no longer exists. These
   rules reproduce the SAME layout keyed on the dynamic widgets' own wrappers.
   The inner card/table/section markup is identical, so all other CSS applies
   unchanged.
   =================================================================== */

/* ---- Menu (Dynamic): subnav + chapter rows ---- */
.dt-menu-dynamic {
    /* Absorb the ≤scrollbar-width 100vw overshoot of the left-bleeding
       decoration cell below (see .dt-menu__deco-cell) so it never adds a
       horizontal scrollbar. The wrapper is full-bleed, so at-edge graphics are
       never clipped — only the off-screen overshoot. */
    overflow-x: clip;
}
.dt-menu-dynamic > .dt-menu-subnav {
    padding-top: 72px; /* 40px (old wrapper) + 32px (subnav) */
}
/* Shop's first Elementor section adds 28px of top padding above the subnav,
   vs Locations' 40px (.e-con-inner) / Menu's 72px subnav padding — both of which
   land the subnav links at the same 235px baseline. Shop falls 12px short, so its
   subnav slides vertically during a Swup transition to/from the other section
   pages. Match the baseline. (.dt-page--shop is the swap container; see header.php.) */
.dt-page--shop .dt-menu-subnav {
    padding-top: 44px; /* 32 base + 12 to reach the shared 235px baseline */
}

/* ---- Sticky subnav (assets/sticky-subnav.js) ----
   The bar pins to the top of the viewport once scrolled past. JS inserts a
   zero-height sentinel + a spacer before the <nav>, toggles `is-stuck`, and
   sets the spacer's height to the bar's resting height so the flow doesn't jump.
   Placed AFTER the page-specific padding-top rules above so the pinned padding
   wins by source order. Pinned padding-top (16px) must match PINNED_PAD in the
   JS so the pills don't jump as the large flow padding collapses. */
.dt-subnav-sentinel,
.dt-subnav-spacer {
    display: block;
    width: 100%;
    height: 0;
}
.dt-menu-subnav.is-stuck {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 50;
    margin: 0;
    padding: 16px 0;
    transition: top 0.3s ease; /* slides down to clear the reveal nav */
}
/* When the reveal nav is shown (scrolled up) it occupies the top, so drop the
   pinned subnav by the nav height to avoid overlap. On scroll-down the reveal
   nav hides, this rule stops applying, and the subnav rides back up to top: 0. */
html.dt-stickynav-shown .dt-menu-subnav.is-stuck {
    top: var(--dt-header-h, 90px);
}
/* Opaque per-page background (content scrolls beneath the pinned bar). Mirrors
   the per-page brand colors on `.dt-page--*` / the body.page-* fallbacks. */
body.page-menu .dt-menu-subnav.is-stuck {
    background: var(--dt-dark-green);
}
body.page-locations .dt-menu-subnav.is-stuck {
    background: var(--dt-slate);
}
body.page-shop .dt-menu-subnav.is-stuck {
    background: var(--dt-rust);
}

.dt-menu__row {
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    align-items: stretch;
    gap: 0;
    width: 100%;
    max-width: var(--dt-canvas);
    margin-inline: auto;
    padding: 80px 0;
}
/* 30%-white divider above every chapter after the first. */
.dt-menu__row + .dt-menu__row {
    border-top: 1px solid rgba(255, 255, 255, 0.3);
}
/* Extra room beneath the final chapter (the footer overlaps upward by 120px). */
.dt-menu-dynamic > .dt-menu__row:last-child {
    padding-bottom: 200px;
}
/* Left decoration cell — fixed width, full row height (flex column so the
   heading bottom-aligns with the last price row). */
.dt-menu__deco-cell {
    /* Grow the cell past the 563px design column as the viewport exceeds the
       1440 canvas, so the decoration fills the space the left-bleed opens up
       instead of leaving a gap before the tables. = 563 at ≤1440. */
    flex: 0 0 auto;
    width: max(563px, calc(563px + (100vw - var(--dt-canvas)) / 2));
    align-self: stretch;
    display: flex;
    flex-direction: column;
    padding: 0;
    /* The negative margin both pulls the cell out to the true left edge AND
       frees the extra main-axis space it grows into, so the tables stay put in
       the centered canvas (margin + width still consume only 563 of the row).
       0 at ≤1440, so small screens are untouched. Mirrors the 100vw full-bleed
       idiom used by .dt-locations-map. */
    margin-left: min(0px, calc((var(--dt-canvas) - 100vw) / 2));
}
/* Right table cell — fills the rest, tables stacked with a gap between them. */
.dt-menu__tables-cell {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 48px;
    padding: 0;
}

/* ---- Locations (Dynamic): 4-col card grid (mirrors the :has() grid above) ---- */
.dt-locations-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 400px));
    column-gap: 20px;
    row-gap: 131px;
    justify-content: center;
    align-content: start;
    align-items: start;
    max-width: 1660px;
    margin-left: auto;
    margin-right: auto;
    /* Always keep a side gutter so cards never run flush to the viewport
       edges once it narrows to roughly the content width. */
    padding-inline: 40px;
}
@media (max-width: 1279px) {
    .dt-locations-grid {
        grid-template-columns: repeat(3, minmax(0, 400px));
    }
}
@media (max-width: 1023px) {
    .dt-locations-grid {
        grid-template-columns: repeat(2, minmax(0, 400px));
        row-gap: 56px;
    }
}
@media (max-width: 768px) {
    .dt-locations-grid {
        grid-template-columns: minmax(0, 1fr);
        padding-inline: 20px;
    }
}

/* Homepage "Our Locations" (Dynamic, capped at 4): align the grid to the sibling
   Section Heading and lay the 4 cards out edge-to-edge across the heading band.
   On the Locations page the same .dt-locations-grid stays a centered 1660px band;
   here we drop that cap, fill the heading's container, and stretch the 4 columns
   so the first/last card line up with the heading's title and arrow link.
   Scoped via :has() to the grid that shares a container with a Section Heading. */
.e-con:has(> .elementor-widget-dt-section-heading) .dt-locations-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    max-width: none;
    margin-left: 0;
    margin-right: 0;
    padding-inline: 0;
    justify-content: stretch;
}
.e-con:has(> .elementor-widget-dt-section-heading) .dt-locations-grid .dt-location-card {
    width: 100%;
    max-width: none;
}
@media (max-width: 1023px) {
    .e-con:has(> .elementor-widget-dt-section-heading) .dt-locations-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}
/* Mobile (Figma 184:245): single-column location cards — the 1-col step moves
   up from 660 to 768 to match the mobile design. */
@media (max-width: 768px) {
    .e-con:has(> .elementor-widget-dt-section-heading) .dt-locations-grid {
        grid-template-columns: minmax(0, 1fr);
        row-gap: 48px;
    }
}

/* ---- Products (Dynamic): the cards are direct children of .dt-product-grid
   (not Elementor elements), so size them the same way as the static grid. ---- */
.dt-product-grid > .dt-product-card {
    flex: 0 0 400px;
    max-width: 400px;
}

/* ---- Filter tabs + client-side filtering (Locations regions / Shop cats) ---- */
/* The tab-style subnav is hidden site-wide per the client's request. */
.dt-menu-subnav--tabs {
    display: none;
}
.dt-menu-subnav--tabs .dt-menu-subnav__item {
    cursor: pointer;
}
.is-filtered-out {
    display: none !important;
}

/* ---- Footer reads olive on the Menu page ----
   The page background is dark, so the whole footer (body + curline wave) flips
   to olive via the single --dt-footer-bg variable, matching the design. */
body.page-menu .dt-site-footer {
    --dt-footer-bg: var(--dt-green);
}

/* ===================================================================
   Locations — Day / Night eyebrow ([clock] Coffee by Day · Wine by Night)
   =================================================================== */
/* Let the widget fill its container (Elementor shrink-wraps it by default), so
   the band below can center against the full container width. */
.elementor-widget-dt-day-night {
    width: 100%;
}
/* Mirror the location-card grid's 1240px centered band so the eyebrow's left
   edge lines up with Card 1 (both at the Figma x=100 page margin) instead of
   the wider 1264px container edge. */
.dt-day-night {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-start;
    align-items: center;
    gap: 40px;
    padding: 30px 40px 0px;
    max-width: 1240px;
    margin-left: auto;
    margin-right: auto;
}
@media (max-width: 768px) {
    .dt-day-night {
        justify-content: center;
        padding-inline: 20px;
    }
}
.dt-day-night__item {
    display: inline-flex;
    align-items: center;
    gap: 21px;
    font-family: var(--dt-font-mono);
    font-weight: 300;
    font-size: 16px;
    line-height: 1.25;
    color: var(--dt-white);
    white-space: nowrap;
}
.dt-day-night__icon {
    width: 18px;
    height: 18px;
    object-fit: contain;
    display: block;
    flex-shrink: 0;
}

/* ===================================================================
   Locations — card grid (2 rows × 3 cols of Location Cards)
   The container holding the Location Cards becomes a 3-col grid. Targeted
   via :has() (like the Menu page) so the page JSON needs no custom class.
   !important overrides Elementor's default .e-con-inner flex so cards lay
   out as a grid rather than stacking.
   =================================================================== */
/* The cards live in a boxed (.e-con-inner) OR full (.e-con) container,
   depending on Elementor's default — target both. */
.e-con-inner:has(> .elementor-widget-dt-location-card),
.e-con:has(> .elementor-widget-dt-location-card) {
    display: grid !important;
    grid-template-columns: repeat(3, minmax(0, 400px)) !important;
    column-gap: 20px !important;
    row-gap: 131px !important; /* Figma: row 2 top (y=1120) − row 1 card bottom (y=989) */
    justify-content: center !important;
    align-content: start;
    align-items: start;
    max-width: 1240px;
    margin-left: auto;
    margin-right: auto;
    padding-inline: 40px;
}
@media (max-width: 1023px) {
    .e-con-inner:has(> .elementor-widget-dt-location-card),
    .e-con:has(> .elementor-widget-dt-location-card) {
        grid-template-columns: repeat(2, minmax(0, 400px)) !important;
        row-gap: 56px !important;
    }
}
@media (max-width: 768px) {
    .e-con-inner:has(> .elementor-widget-dt-location-card),
    .e-con:has(> .elementor-widget-dt-location-card) {
        grid-template-columns: minmax(0, 1fr) !important;
        padding-inline: 20px;
    }
}

/* Homepage "Our Locations": align the card grid to the Section Heading.
   The heading fills its container (the page's 72px side padding), but the card
   grid was a centered max-width:1240px band, so Card 1 / the last card sat ~28px
   inside the heading's title and arrow link. Let the grid fill the same container
   band and stretch the cards to match it, so the card row's left/right edges line
   up with the heading. Scoped via :has() to the grid that shares a container with
   a Section Heading — the Locations page grid + Day/Night eyebrow are untouched. */
.e-con:has(> .elementor-widget-dt-section-heading) :is(.e-con, .e-con-inner):has(> .elementor-widget-dt-location-card) {
    max-width: none !important;
    grid-template-columns: repeat(3, 1fr) !important;
    justify-content: stretch !important;
    margin-left: 0 !important;
    margin-right: 0 !important;
    padding-inline: 0 !important;
}
.e-con:has(> .elementor-widget-dt-section-heading) .elementor-widget-dt-location-card {
    width: 100%;
}
.e-con:has(> .elementor-widget-dt-section-heading) .dt-location-card {
    width: 100%;
    max-width: none;
}
@media (max-width: 1023px) {
    .e-con:has(> .elementor-widget-dt-section-heading) :is(.e-con, .e-con-inner):has(> .elementor-widget-dt-location-card) {
        grid-template-columns: repeat(2, 1fr) !important;
    }
}
@media (max-width: 660px) {
    .e-con:has(> .elementor-widget-dt-section-heading) :is(.e-con, .e-con-inner):has(> .elementor-widget-dt-location-card) {
        grid-template-columns: minmax(0, 1fr) !important;
    }
}

/* ===================================================================
   Locations — full-bleed interactive Leaflet map with slate pins.
   The .dt-locations-map element IS the Leaflet container; markers reuse the
   original slate teardrop SVG so the section looks unchanged.
   =================================================================== */
.dt-locations-map {
    position: relative;
    width: 100vw;
    left: 50%;
    right: 50%;
    margin-left: -50vw;
    margin-right: -50vw;
    margin-top: 96px;
    height: clamp(420px, 56vw, 798px); /* no <img> sets the height now */
    background: var(--dt-slate);       /* shows through before tiles load */
    z-index: 0;                        /* keep Leaflet panes below the footer */
}

/* The teardrop divIcon marker — strip Leaflet's default white box and let the
   SVG fill the icon, anchored at its tip (set in JS via iconAnchor). */
.dt-map-pin {
    background: transparent;
    border: 0;
}
.dt-map-pin svg {
    display: block;
    width: 100%;
    height: 100%;
    filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.25));
}

/* Hover tooltip — the dark-green pill from the original pin label. */
.leaflet-tooltip.dt-map-tooltip {
    padding: 4px 10px;
    background: var(--dt-dark-green);
    color: var(--dt-white);
    font-family: var(--dt-font-mono);
    font-size: 13px;
    line-height: 1.4;
    white-space: nowrap;
    border: 0;
    border-radius: 4px;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
}
.leaflet-tooltip.dt-map-tooltip::before {
    border-top-color: var(--dt-dark-green);
}

/* Click popup — title + address, on-brand type. The popup wrapper is an <a>,
   so Leaflet's base `.leaflet-container a { color:#0078A8 }` (light blue) would
   otherwise win for the address line, and the popup-content wrapper defaults to
   Leaflet's #333. Force every bit of popup type to the brand dark-green
   (#081c13), and recolor Leaflet's close (×) button to match. */
.dt-map-popup,
.dt-locations-map .leaflet-popup-content-wrapper,
.dt-locations-map .leaflet-popup-content,
.dt-locations-map .leaflet-popup-content a.dt-map-popup,
.dt-locations-map .leaflet-popup-content a.dt-map-popup .dt-map-popup__title,
.dt-locations-map .leaflet-popup-content a.dt-map-popup .dt-map-popup__addr,
.dt-locations-map .leaflet-popup-close-button,
.dt-locations-map .leaflet-popup-close-button span {
    color: var(--dt-dark-green);
}
.dt-map-popup {
    display: block;
    font-family: var(--dt-font-mono);
    text-decoration: none;
}
.dt-map-popup__title {
    display: block;
    font-size: 15px;
}
.dt-map-popup__addr {
    display: block;
    margin-top: 4px;
    font-size: 13px;
    line-height: 1.4;
}
a.dt-map-popup:hover .dt-map-popup__title {
    text-decoration: underline;
}

/* Tone Leaflet's chrome toward the brand. */
.dt-locations-map .leaflet-bar a {
    color: var(--dt-dark-green);
}
.dt-locations-map .leaflet-control-attribution {
    font-family: var(--dt-font-mono);
    font-size: 10px;
}

/* ===================================================================
   Location Card action links use the hand-drawn Figma arrows (down arrow
   for Download Menu, right arrow for Order Now) — distinct from the
   app-wide long decorative arrow. Inlined SVGs inherit the link colour.
   =================================================================== */
.dt-arrow-link--arrow-down,
.dt-arrow-link--arrow-diag {
    gap: 12px;
}
.dt-arrow-link--arrow-down .dt-arrow-link__icon {
    width: 8px;
    height: 17px;
}
.dt-arrow-link--arrow-diag .dt-arrow-link__icon {
    width: 17px;
    height: 8px;
}
/* On hover the short hand-drawn arrows slide in the direction they point —
   the down arrow (Download Menu) nudges down, the right arrow (Order Now)
   nudges right — mirroring the long arrow's slide. The text underline grows
   in via the shared .dt-arrow-link__text::after rule in the animation block. */
.dt-arrow-link--arrow-down:hover .dt-arrow-link__icon {
    transform: translateY(4px);
}
.dt-arrow-link--arrow-diag:hover .dt-arrow-link__icon {
    transform: translateX(6px);
}

/* ===================================================================
   Shop / Products page — Product Card + Cross Promo (Foggia strip).
   Background = rust (#955323). Reference: docs/figma-screens.md §3,
   docs/screenshots/03-products.png.
   =================================================================== */

/* Grid wrapper applied (via "CSS Classes") to the Elementor container holding
   the cards. Left-aligned to the Foggia card's 210px left edge (matching
   .dt-cross-promo below) so the first card lines up above the Foggia logo.
   At the 1440 canvas this fits 2 cards per row (210 + 1244 > 1440); cards wrap
   responsibly via flex-wrap + .dt-product-card max-width:100%. !important
   overrides Elementor's default container flex-direction (column). */
.dt-product-grid,
.elementor-element-dtsgrid1 {
    display: flex !important;
    flex-direction: row !important;
    flex-wrap: wrap !important;
    justify-content: flex-start !important;
    align-items: flex-start !important;
    gap: 22px !important;
    max-width: none;
    margin-left: 0;
    margin-right: 0;
    padding-left: 210px;
}
.dt-product-grid > .elementor-element,
.elementor-element-dtsgrid1 > .elementor-element {
    flex: 0 0 400px;
    max-width: 400px;
}

/* ---- Product Card: 400×492 — banner (15px radius, all corners) + olive
   pill + title + description + price. ---- */
.dt-product-card {
    display: block;
    width: 400px;
    min-height: 492px; /* Figma card frame is a fixed 400×492 — keeps the row
                          gap reading as the design's 22px (not collapsed). */
    max-width: 100%;
    color: var(--dt-white);
    font-family: var(--dt-font-mono);
    text-decoration: none;
}
.dt-product-card__banner {
    position: relative;
    margin-bottom: 27px;
}
.dt-product-card__banner img {
    display: block;
    width: 100%;
    height: 261px;
    object-fit: cover;
    border-radius: var(--dt-radius); /* 15px — all four corners */
}
/* Pill sits over the banner, flush to the left edge (Figma x=0, y=16). */
.dt-product-card__pill {
    position: absolute;
    top: 16px;
    left: 0;
    z-index: 2;
}
/* Internal spacing mirrors the Figma y-positions (card-relative): banner 0–261,
   title 288, description 340, price 424. */
.dt-product-card__title {
    margin: 0 0 24px;
    font-family: var(--dt-font-display);
    font-weight: 700;
    font-size: 20px;
    line-height: 28px;
    letter-spacing: 0.04em;
    text-transform: uppercase; /* Figma renders titles uppercase (e.g. "SAUZ") */
    color: var(--dt-white);
}
.dt-product-card__body {
    margin: 0;
    min-height: 84px; /* Figma reserves an 84px description box (y=340→424). */
    font-weight: 300;
    font-size: var(--dt-body-size);
    line-height: var(--dt-body-lh);
    color: var(--dt-white);
}
.dt-product-card__price {
    margin: 0;
    font-family: var(--dt-font-display);
    font-weight: 700;
    font-size: 20px;
    line-height: 28px;
    letter-spacing: 0.04em;
    color: var(--dt-white);
}

/* ---- Cross Promo (Foggia strip): logo left, tagline/body/arrow right.
   Figma: logo 382×107 at x=210, text column 593px at x=730. ---- */
.dt-cross-promo {
    display: flex;
    align-items: center;
    gap: 138px;
    padding: 0 117px 0 210px;
    color: var(--dt-white);
}
.dt-cross-promo__logo {
    flex: 0 0 auto;
}
.dt-cross-promo__logo img {
    display: block;
    width: 100%; /* capped by the widget's logo_max_width control (382px) */
    height: auto;
}
.dt-cross-promo__content {
    flex: 1 1 auto;
    max-width: 593px;
}
.dt-cross-promo__tagline {
    margin: 0 0 16px;
    font-family: var(--dt-font-display);
    font-weight: 700;
    font-size: var(--dt-tagline-size);
    line-height: var(--dt-tagline-lh);
    letter-spacing: var(--dt-tagline-track);
    /* As-typed (lowercase) per Figma node 79:1778 — no uppercase transform. */
    color: var(--dt-white);
    white-space: pre-line;
}
.dt-cross-promo__body {
    margin: 0 0 24px;
    /* Set the family explicitly (Roboto Mono per Figma node 79:1779) — relying on
       inheritance fell back to serif here because Elementor's global kit overrides
       the theme's body font-family. */
    font-family: var(--dt-font-mono);
    font-weight: 300;
    font-size: var(--dt-body-size);
    line-height: var(--dt-body-lh);
    color: var(--dt-white);
}

/* ============================================================================
   MOTION — scroll reveals, hero load choreography, page transitions, hovers
   ----------------------------------------------------------------------------
   Every start-state lives under `html.dt-anim-ready` (added by assets/scroll-
   reveal.js in the <head>, before paint) AND inside the no-preference media
   query. So content is fully visible and static when:
     - JS hasn't run / failed (class never added),
     - we're in the Elementor editor (asset not enqueued), or
     - the user prefers reduced motion (media query doesn't match).
   Reveal direction is encoded per selector here; the JS only decides WHEN an
   element gets `.is-visible`. Stagger comes from JS timing, so the transition
   below stays constant and is safe to reuse for hover micro-motion.
   ============================================================================ */

@keyframes dt-hero-rise {
    from { opacity: 0; transform: translateY(20px); }
    to   { opacity: 1; transform: none; }
}

@keyframes dt-hero-pulse {
    0%, 100% { transform: translateY(0); opacity: .85; }
    50%      { transform: translateY(4px); opacity: 1; }
}

/* Logo variant of the rise — keeps the −50%/−50% centering translate so the
   absolutely-centered hero logo animates in place instead of jumping down-right
   when the generic `transform: none` end-state wipes its centering. */
@keyframes dt-hero-rise-logo {
    from { opacity: 0; transform: translate(-50%, calc(-50% + 20px)); }
    to   { opacity: 1; transform: translate(-50%, -50%); }
}

@media (prefers-reduced-motion: no-preference) {

    /* No cross-page transition: the body is never hidden, so internal links
       navigate instantly — no fade-out delay, no blank flash. */

    /* ---- Scroll-reveal: shared hidden state + transition ---------------- */
    .dt-anim-ready .dt-two-col__image-wrap,
    .dt-anim-ready .dt-two-col__content,
    .dt-anim-ready .dt-gift-cards-hero__image,
    .dt-anim-ready .dt-gift-cards-hero__content,
    .dt-anim-ready .dt-rewards-hero__image,
    .dt-anim-ready .dt-rewards-hero__content,
    .dt-anim-ready .dt-location-card,
    .dt-anim-ready .dt-product-card,
    .dt-anim-ready .dt-ig-tile,
    .dt-anim-ready .dt-section-heading,
    .dt-anim-ready .dt-cross-promo,
    .dt-anim-ready .dt-locations-map,
    .dt-anim-ready .dt-privacy,
    .dt-anim-ready .dt-menu-section__deco,
    .dt-anim-ready .dt-menu-category,
    .dt-anim-ready .dt-day-night,
    .dt-anim-ready .dt-site-footer__col {
        opacity: 0;
        transition: opacity .7s cubic-bezier(.22, .61, .36, 1),
                    transform .45s cubic-bezier(.22, .61, .36, 1);
        will-change: opacity, transform;
    }

    /* Directional start transforms (image slides in from the left, text from
       the right). Subtle 32px travel per the "refined" brief. */
    .dt-anim-ready .dt-two-col__image-wrap,
    .dt-anim-ready .dt-gift-cards-hero__image,
    .dt-anim-ready .dt-rewards-hero__image {
        transform: translateX(-32px);
    }
    .dt-anim-ready .dt-two-col__content,
    .dt-anim-ready .dt-gift-cards-hero__content,
    .dt-anim-ready .dt-rewards-hero__content {
        transform: translateX(32px);
    }

    /* Rise (gentle upward fade). Instagram tiles are intentionally fade-only. */
    .dt-anim-ready .dt-location-card,
    .dt-anim-ready .dt-product-card,
    .dt-anim-ready .dt-section-heading,
    .dt-anim-ready .dt-cross-promo,
    .dt-anim-ready .dt-locations-map,
    .dt-anim-ready .dt-privacy,
    .dt-anim-ready .dt-menu-section__deco,
    .dt-anim-ready .dt-menu-category,
    .dt-anim-ready .dt-day-night,
    .dt-anim-ready .dt-site-footer__col {
        transform: translateY(24px);
    }

    /* Revealed. Only reveal targets ever receive `.is-visible`. */
    .dt-anim-ready .is-visible {
        opacity: 1;
        transform: none;
    }

    /* Page transition: fade the LEAVING page's CONTENT out as the gradient
       sweeps over it. page-transitions.js adds `.is-leaving` to the outgoing
       #dt-swup at visit:start. We fade the whole content area — every direct
       child except the persistent header — so ALL changing content dissolves
       uniformly (subnav, headings, cards, menu rows, map…), not just the
       scroll-reveal elements. The brand background color lives on #dt-swup
       itself (not on this content wrapper), so it is NOT faded: the content
       melts into the page color, preserving the contextual color reveal. The
       header is excluded — it is carried across by the gradient sweep instead. */
    #dt-swup.is-leaving > :not(.elementor-location-header) {
        opacity: 0;
        transition: opacity 0.6s cubic-bezier(.22, .61, .36, 1);
    }

    /* ---- Hero load choreography (homepage full-bleed hero) -------------- */
    .dt-anim-ready .dt-hero__logo,
    .dt-anim-ready .dt-hero__headline,
    .dt-anim-ready .dt-hero__eyebrow {
        opacity: 0;
    }
    .dt-anim-ready.dt-hero-ready .dt-hero__logo {
        animation: dt-hero-rise-logo .9s cubic-bezier(.22, .61, .36, 1) .15s both;
    }
    .dt-anim-ready.dt-hero-ready .dt-hero__headline {
        animation: dt-hero-rise .9s cubic-bezier(.22, .61, .36, 1) .45s both;
    }
    .dt-anim-ready.dt-hero-ready .dt-hero__eyebrow {
        animation: dt-hero-rise .9s cubic-bezier(.22, .61, .36, 1) .75s both;
    }
    .dt-anim-ready.dt-hero-ready .dt-hero__arrow {
        animation: dt-hero-pulse 1.9s ease-in-out 1.9s infinite;
    }

    /* ---- Hover micro-motion (color only — card/tile lift disabled) ------
       Location/product cards and IG tiles previously lifted translateY(-4px)
       on hover; the client opted out of that motion, so there is no transform
       on hover. Links/buttons keep their color & opacity easing below. */

    /* Smooth color / opacity easing on links + a subtle lift on the one real
       button (the footer subscribe submit). Arrow-links keep their existing
       arrow-slide hover from earlier in this file. */
    .dt-anim-ready .dt-main-nav a,
    .dt-anim-ready .dt-arrow-link,
    .dt-anim-ready .dt-arrow-link__text,
    .dt-anim-ready .dt-site-footer__contact-link {
        transition: color .25s ease, opacity .25s ease;
    }
    .dt-anim-ready .dt-site-footer__form button {
        transition: transform .25s ease, opacity .25s ease;
    }
    .dt-anim-ready .dt-site-footer__form button:hover {
        transform: translateY(-2px);
    }

    /* ---- Main nav: active underline draws in on load ------------------- */
    .dt-anim-ready .dt-nav-active::after {
        transform: scaleX(0);
        transform-origin: center;
        transition: transform .55s cubic-bezier(.22, .61, .36, 1) .25s;
    }
    .dt-anim-ready.dt-shown .dt-nav-active::after {
        transform: scaleX(1);
    }

    /* Non-active nav items grow the same underline in on hover. */
    .dt-anim-ready .dt-main-nav__item:not(.dt-nav-active) > a {
        position: relative;
    }
    .dt-anim-ready .dt-main-nav__item:not(.dt-nav-active) > a::after {
        content: "";
        position: absolute;
        left: 0;
        right: 0;
        bottom: -6px;
        height: 2px;
        border-radius: 2px;
        background: var(--dt-white);
        transform: scaleX(0);
        transform-origin: center;
        transition: transform .28s cubic-bezier(.22, .61, .36, 1);
    }
    .dt-anim-ready .dt-main-nav__item:not(.dt-nav-active) > a:hover::after {
        transform: scaleX(1);
    }

    /* Arrow-links grow the same underline under their text on hover (on top of
       the arrow-slide), so hover reads as clearly as it does in the main nav.
       Scoped to the text span so it never runs under the arrow icon, and uses
       currentColor since these links sit on white, rust, and dark backgrounds. */
    .dt-anim-ready .dt-arrow-link__text {
        position: relative;
    }
    .dt-anim-ready .dt-arrow-link__text::after {
        content: "";
        position: absolute;
        left: 0;
        right: 0;
        bottom: -4px;
        height: 2px;
        border-radius: 2px;
        background: currentColor;
        transform: scaleX(0);
        transform-origin: center;
        transition: transform .28s cubic-bezier(.22, .61, .36, 1);
    }
    .dt-anim-ready .dt-arrow-link:hover .dt-arrow-link__text::after {
        transform: scaleX(1);
    }

    /* ---- Menu subnav: the active squiggle cross-fades between items ----- */
    /* Give every item the (hidden) squiggle so toggling `--active` animates a
       smooth fade+scale from the old item to the new one (menu-subnav.js moves
       the class on click). Overrides the static single-item rule above. */
    .dt-anim-ready .dt-menu-subnav__item::after {
        content: "";
        position: absolute;
        left: 50%;
        bottom: -12px;
        width: 73px;
        height: 10px;
        background-color: var(--dt-subnav-underline, #9cb6be);
        -webkit-mask: url(assets/subnav-active.svg) no-repeat center / contain;
        mask: url(assets/subnav-active.svg) no-repeat center / contain;
        opacity: 0;
        transform: translateX(-50%) scaleX(.5);
        transition: opacity .3s ease, transform .3s cubic-bezier(.22, .61, .36, 1);
        pointer-events: none;
    }
    .dt-anim-ready .dt-menu-subnav__item--active::after {
        opacity: 1;
        transform: translateX(-50%) scaleX(1);
    }
}

/* =========================================================================
   Swup page transitions — contextual "gradient reveal"
   The swap container (#dt-swup.dt-page) wraps the header + page content and
   carries each page's brand background color; the Parallel plugin keeps the
   outgoing + incoming containers stacked in one grid cell, and a sweeping
   gradient mask reveals the incoming page — header and all — and its color over
   the outgoing one (assets/page-transitions.js). A faithful port of the official
   Swup reveal/gradient demo, ungated because the gradient is our only
   transition. Resting pages are never masked, so this is inert unless a
   navigation is in flight.
   ========================================================================= */
/* Only become a stacking grid DURING a transition. A `display:grid` wrapper here
   at rest triggers a Chrome paint bug that blanks the footer curline's CSS mask
   (the curline is in a sibling subtree). Block at rest keeps the curline intact;
   grid during the change overlaps the outgoing + incoming containers in one cell
   for the reveal. */
html.is-changing .dt-pages {
    display: grid;
}
.dt-page {
    grid-area: 1 / 1; /* (inert until .dt-pages is grid) share one cell to overlap */
    min-width: 0;
}
/* A page only needs to lift above its siblings while the transition grid is
   overlapping the outgoing + incoming containers. At rest a single page must
   stay BELOW the footer so the curline can leak up over it (the footer is
   position:relative z-index:1 with margin-top:-120px). Keeping z-index off the
   resting page matters specifically on Home: .dt-page--home is position:relative
   for its absolute header, which would otherwise activate this z-index at rest
   and bury the curline under the page's opaque background. Scoping it to
   html.is-changing makes Home behave like every other page at rest. */
html.is-changing .dt-page {
    z-index: 2; /* grid items honor z-index without positioning */
}
.dt-page + .dt-page {
    z-index: 1;
}

/* Per-page container color (mirrors the body.page-* fallbacks) so the reveal
   exposes the next page's color. Unknown slugs fall through to the body bg. */
.dt-page--home,
.dt-page--rewards {
    background: var(--dt-green);
}
.dt-page--locations,
.dt-page--gift-cards {
    background: var(--dt-slate);
}
.dt-page--shop,
.dt-page--products,
.dt-page--privacy {
    background: var(--dt-rust);
}
.dt-page--menu {
    background: var(--dt-dark-green);
}

/* The sweeping gradient mask — present only while a transition is in flight. */
html.is-changing .transition-reveal {
    transition: -webkit-mask-position 0.9s cubic-bezier(0.5, 0, 0.15, 1),
        mask-position 0.9s cubic-bezier(0.5, 0, 0.15, 1);
}
html.is-changing .dt-page {
    -webkit-mask-image: linear-gradient(to left, transparent 33.33%, #000 66.66%);
    mask-image: linear-gradient(to left, transparent 33.33%, #000 66.66%);
    -webkit-mask-size: 300% 100%;
    mask-size: 300% 100%;
    -webkit-mask-position: 0%;
    mask-position: 0%;
}
html.is-changing .dt-page + .dt-page {
    -webkit-mask-position: 100%;
    mask-position: 100%;
    z-index: 3; /* incoming sits on top while it reveals over the outgoing */
}

/* Reduced motion: Swup itself is skipped in JS; guard the mask defensively. */
@media (prefers-reduced-motion: reduce) {
    html.is-changing .dt-page,
    html.is-changing .dt-page + .dt-page {
        -webkit-mask: none;
        mask: none;
    }
}

/* =========================================================================
   RESPONSIVE — tablet (≤1024px) + mobile (≤768px)
   Desktop (>1024px) is intentionally untouched: every rule below lives inside
   a max-width media query (the only non-query addition is the hamburger button,
   which is display:none by default). The mobile layer (≤768) follows the Figma
   mobile frame 184:245 (402px canvas, 32px side gutter); the tablet layer
   (769–1024) reuses the single-column structure with looser spacing.
   Reference: docs/screenshots/mobile-homepage.png.
   ========================================================================= */

/* ---- Hamburger toggle — rendered in every .dt-main-nav (resting + sticky
   clone). Hidden on desktop; revealed at ≤1024px. Three 21×2 bars (Figma). ---- */
.dt-main-nav__toggle {
    display: none;
    flex-direction: column;
    align-items: flex-end;
    justify-content: center;
    gap: 5.5px;
    width: 36px;
    height: 36px;
    flex-shrink: 0;
    padding: 0;
    margin: 0;
    background: none;
    border: 0;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
}
.dt-main-nav__toggle span {
    display: block;
    width: 21px;
    height: 2px;
    border-radius: 2px;
    background: #f0eeea;
}

/* ---- Full-screen mobile menu overlay (built by assets/mobile-nav.js, appended
   to <body> as a single shared instance). Figma has no open state — this is the
   on-brand panel: dark-green field, links stacked + centered. ---- */
.dt-mobile-menu {
    position: fixed;
    inset: 0;
    z-index: 100; /* above the sticky reveal nav (60) */
    display: flex;
    flex-direction: column;
    align-items: center;
    /* space-between seats the logo at the top, links in the middle and the
       socials at the bottom (client review). Top padding clears the close ×. */
    justify-content: space-between;
    padding: 72px 24px 48px;
    background: var(--dt-dark-green);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 0.3s ease, visibility 0.3s ease;
}
.dt-mobile-menu.is-open {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
}
.dt-mobile-menu__close {
    position: absolute;
    top: 24px;
    right: 24px;
    width: 44px; /* tap target */
    height: 44px;
    padding: 0;
    background: none;
    border: 0;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
}
.dt-mobile-menu__close span {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 26px;
    height: 2px;
    border-radius: 2px;
    background: var(--dt-white);
}
.dt-mobile-menu__close span:first-child {
    transform: translate(-50%, -50%) rotate(45deg);
}
.dt-mobile-menu__close span:last-child {
    transform: translate(-50%, -50%) rotate(-45deg);
}
.dt-mobile-menu__list {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 28px;
    margin: 0;
    padding: 0;
    list-style: none;
}
.dt-mobile-menu__list a {
    font-family: var(--dt-font-display);
    font-weight: 700;
    font-size: 28px;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--dt-white);
    text-decoration: none;
}
/* White dialtone logo seated above the links (cloned from the footer/nav). */
.dt-mobile-menu__logo {
    width: 160px;
}
.dt-mobile-menu__logo img {
    display: block;
    width: 100%;
    height: auto;
}
/* Social icons pinned to the bottom of the overlay. */
.dt-mobile-menu__socials {
    display: flex;
    gap: 24px;
    margin: 0;
    padding: 0;
    list-style: none;
}
.dt-mobile-menu__socials img {
    display: block;
    width: 24px;
    height: 24px;
}
/* Lock background scroll while the overlay is open (toggled on <html> by JS). */
html.dt-menu-open {
    overflow: hidden;
}
@media (prefers-reduced-motion: reduce) {
    .dt-mobile-menu {
        transition: none;
    }
}

/* ===== Tablet + mobile structural layer (≤1024px) ===== */
@media (max-width: 1024px) {
    /* Nav → hamburger: hide the desktop link groups, reveal the toggle. The
       sticky clone reuses these rules, so it collapses identically. */
    .dt-main-nav__group {
        display: none;
    }
    .dt-main-nav__toggle {
        display: inline-flex;
    }
    .dt-main-nav {
        padding: 0 48px;
    }

    /* Hero: trim the desktop 1024px min-height / 108px padding for tablets. */
    .dt-hero {
        min-height: 720px;
        padding: 48px;
    }

    /* Two-column intros stack to one column, text first / image last for BOTH
       variants. The widget sets padding inline, so !important is required. */
    .dt-two-col,
    .dt-two-col--image-right {
        grid-template-columns: 1fr !important;
        gap: 0;
        padding: 64px 48px !important;
    }
    .dt-two-col__content,
    .dt-two-col--image-right .dt-two-col__content {
        order: 1;
        max-width: none;
    }
    .dt-two-col__image-wrap {
        order: 2;
        margin-top: 40px;
    }

    /* Footer columns stack into one centered column. */
    .dt-site-footer__body {
        padding: 64px 48px 40px;
    }
    .dt-site-footer__row--main {
        grid-template-columns: 1fr;
        gap: 40px;
        text-align: center;
    }
    /* Meta row: disclaimer full-width on top, then payments + back-to-top button
       share the same row (button is static/in-flow on tablet/mobile so it has
       a dedicated visual slot instead of floating over footer content). */
    .dt-site-footer__row--meta {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: 16px;
    }
    .dt-site-footer__disclaimer {
        width: 100%;
        order: -1;
        text-align: center;
    }
    .dt-site-footer__payments {
        flex: 1;
        justify-content: flex-start;
        min-width: 0;
    }
    /* Shift the fixed button to match the 32px mobile/tablet content gutter. */
    .dt-site-footer__top {
        right: 32px;
    }
}

/* ===== Tablet-only footer form overrides (769px–1024px) ===== */
@media (min-width: 769px) and (max-width: 1024px) {
    /* Constrain the subscribe form to match the heading text width, centered. */
    .dt-site-footer__form,
    .dt-site-footer__form-fallback {
        max-width: 325px;
        margin-left: auto;
        margin-right: auto;
    }
    /* The stacked footer uses text-align:center, which centers placeholder text
       in inputs — override to keep it left-aligned like a normal input field. */
    .dt-site-footer__form .gform_wrapper input[type="email"],
    .dt-site-footer__form .gform_wrapper input[type="text"],
    .dt-site-footer__form-fallback input[type="email"] {
        text-align: left !important;
    }
}

/* ===== Mobile / Figma layer (≤768px) — frame 184:245 ===== */
@media (max-width: 768px) {
    /* Tighter page gutter on phones (client review: nav felt too padded). */
    .dt-main-nav {
        padding: 0 20px;
    }

    /* Let the bar grow so the message can stack onto two lines with breathing
       room instead of being clipped by the fixed 30px desktop height. Symmetric
       padding keeps the centred text clear of the absolute close (×) button. */
    .dt-notification-bar {
        height: auto;
        min-height: 30px;
        padding: 8px 36px;
    }
    .dt-notification-bar__text {
        line-height: 1.4;
        text-align: center;
    }

    /* Hero — Figma 402×840: 30% scrim (kept), centered 281px logo, bottom-left
       headline (40px) + eyebrow (16px). Height tracks the Figma proportion. */
    .dt-hero {
        min-height: 100vh; /* fallback for browsers without svh */
        min-height: min(840px, 100svh);
        padding: 32px 32px 48px;
    }
    .dt-hero__logo {
        width: 281px;
        max-width: 100%;
    }

    /* The two two-column widgets sit in Elementor containers with INCONSISTENT
       side padding (intro: 0 left; Featured Products: ~19.5px both sides), which
       otherwise indents the Products content. Zero those containers' horizontal
       padding on mobile so both sections span the full width and share the same
       32px gutter supplied by the .dt-two-col padding below. */
    .e-con:has(> .elementor-element .dt-two-col) {
        padding-left: 0 !important;
        padding-right: 0 !important;
    }
    .dt-two-col,
    .dt-two-col--image-right {
        display: flex;
        flex-direction: column;
        align-items: stretch; /* override base align-items:center so content fills
                                 the gutter and each image bleeds to its own edge */
        padding: 64px 32px !important;
    }
    /* Simple Sip (image-left): image bleeds LEFT to the screen edge; rounded on
       the top-right, bottom-right AND bottom-left (only top-left is square). */
    .dt-two-col .dt-two-col__image-wrap {
        margin-left: -32px;
        align-items: flex-start;
    }
    .dt-two-col .dt-two-col__image {
        border-radius: 0 var(--dt-radius) var(--dt-radius) var(--dt-radius);
    }
    /* Featured Products (image-right): inset 32px on the left, bleeds to the
       screen edge on the right, all four corners rounded, per Figma. */
    .dt-two-col--image-right .dt-two-col__image-wrap {
        margin-left: 0;
        margin-right: -32px;
        align-items: flex-end;
    }
    .dt-two-col--image-right .dt-two-col__image {
        border-radius: var(--dt-radius) 0 0 var(--dt-radius);
        will-change: transform; /* force own compositor layer; parent will-change causes stale border-radius cache */
    }
    /* Keep the featured wine decoration anchored to the image's bottom-right.
       Desktop sets inline --dt-deco-x:-95px and an inline max-width:168px on
       the img, both of which must be overridden on mobile. Per the Figma mobile
       frame the decoration is centred on the bottom edge (half inside, half
       below), so translateY(50%) shifts it down by 50% of its own height. */
    .dt-two-col--image-right .dt-two-col__decoration--bottom-right {
        --dt-deco-x: 0px;
        --dt-deco-y: 0px;
        right: 0;
        transform: translateY(50%);
    }
    .dt-two-col__decoration img {
        max-width: 126px !important;
    }

    /* Section heading: stack the 72px title above any right-side arrow-link. */
    .dt-section-heading {
        flex-direction: column;
        align-items: flex-start;
        gap: 16px;
    }

    /* Hide the right-side arrow link in section headings on mobile (e.g. "Location Details" on homepage). */
    .dt-section-heading__link {
        display: none;
    }

    /* Location card: fill the full grid column (overrides hardcoded width: 400px). */
    .dt-locations-grid .dt-location-card,
    .e-con-inner:has(> .elementor-widget-dt-location-card) .dt-location-card,
    .e-con:has(> .elementor-widget-dt-location-card) .dt-location-card {
        width: 100%;
    }

    /* Location card banner height per Figma (desktop is 261px). */
    .dt-location-card__banner img {
        height: 222px;
    }

    /* Footer: 32px gutter on mobile. */
    .dt-site-footer__body {
        padding: 48px 32px 40px;
    }
}

/* ===================================================================
   Shop / Products page — responsive overrides
   Desktop aligns the product grid and cross-promo to a 210px left inset
   so the first card sits above the Foggia logo. On tablet/mobile that
   gutter resets to the standard page gutter (48px / 32px); cards reflow
   to 2 columns (tablet) or 1 column (mobile); the cross-promo stacks
   vertically on mobile.
   =================================================================== */

/* Tablet (≤1024px): 2-column product grid, standard gutter. */
@media (max-width: 1024px) {
    .dt-product-grid,
    .elementor-element-dtsgrid1 {
        padding-left: 48px !important;
        padding-right: 48px !important;
    }
    /* Elementor-wrapped cards (static widget placement). */
    .dt-product-grid > .elementor-element,
    .elementor-element-dtsgrid1 > .elementor-element {
        flex: 0 0 calc(50% - 11px) !important;
        max-width: calc(50% - 11px) !important;
    }
    /* Direct-child cards from the Products (Dynamic) widget. */
    .dt-product-grid > .dt-product-card {
        flex: 0 0 calc(50% - 11px);
        max-width: calc(50% - 11px);
    }
    /* Cross-promo: tighten padding and gap; shrink logo to give content room. */
    .dt-cross-promo {
        gap: 40px;
        padding: 0 48px;
    }
    .dt-cross-promo__logo {
        max-width: 180px;
    }
}

/* Mobile (≤768px): single-column grid, stacked cross-promo. */
@media (max-width: 768px) {
    .dt-product-grid,
    .elementor-element-dtsgrid1 {
        padding-left: 32px !important;
        padding-right: 32px !important;
    }
    .dt-product-grid > .elementor-element,
    .elementor-element-dtsgrid1 > .elementor-element {
        flex: 1 1 100% !important;
        max-width: 100% !important;
    }
    .dt-product-grid > .dt-product-card {
        flex: 1 1 100%;
        max-width: 100%;
        width: 100%;
    }
    /* Cross-promo: logo stacks above content. */
    .dt-cross-promo {
        flex-direction: column;
        align-items: flex-start;
        gap: 24px;
        padding: 0 32px 40px;
    }
    .dt-cross-promo__logo {
        max-width: 200px;
    }
}

/* =========================================================================
   Small-phone (≤600px) type & spacing — ported from the client's Customizer
   tweaks so they live in version control instead of the DB.
   ========================================================================= */
@media (max-width: 600px) {
    h1,
    .dt-section-heading__title {
        font-size: 50px !important;
        line-height: 1.2em !important;
    }
    .dt-two-col__tagline {
        font-size: 20px;
        line-height: 1.2em;
    }
    /* One specific section heading shrunk further (per-element override). */
    .elementor-element-46d2799 .dt-section-heading__title {
        font-size: 24px !important;
    }
    .dt-hero {
        gap: 10px;
        padding-bottom: 25px;
    }
    .dt-hero .dt-hero__headline {
        font-size: 30px;
    }
    .dt-hero .dt-hero__eyebrow {
        font-size: 14px;
    }
    .dt-location-card__actions .dt-arrow-link {
        font-size: 16px;
    }
}
