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

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

/* =========================================================================
   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__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 {
    width: 100%;
    height: 30px;
    display: flex;
    align-items: center;
    justify-content: center;
}
.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);
}

/* 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: 113px;
    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;
}
.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;
}
.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);
}
.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%;
}
.dt-two-col__image img {
    width: 100%;
    height: auto;
    display: block;
}
/* 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;
    gap: 20px;
    margin-bottom: 56px;
}
.dt-rewards-hero__mug {
    display: inline-flex;
    width: 47px;
    height: 45px;
    color: var(--dt-white); /* white mugs */
}
.dt-rewards-hero__mug--gold {
    color: var(--dt-gold); /* the last N mugs */
}
.dt-rewards-hero__mug-icon {
    display: block;
    width: 100%;
    height: 100%;
}
.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__image,
    .dt-rewards-hero__content {
        flex: none;
        width: 100%;
        max-width: 100%;
    }
    .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 img {
    display: block;
    width: 59.56px;
    height: 37.28px;
}
@media (max-width: 1024px) {
    .dt-gift-cards-hero {
        flex-direction: column;
        gap: 40px;
        padding: 40px 24px;
    }
    .dt-gift-cards-hero__image,
    .dt-gift-cards-hero__content {
        flex: none;
        width: 100%;
        max-width: 100%;
    }
}

/* 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;
    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));
    }
}
@media (max-width: 660px) {
    .dt-ig-grid {
        grid-template-columns: repeat(2, minmax(0, 232px));
        column-gap: 16px;
        row-gap: 28px;
    }
}

/* =========================================================================
   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;
}
/* 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: 660px) {
    .dt-locations-grid {
        grid-template-columns: minmax(0, 400px);
        padding-inline: 20px;
    }
}

/* ---- 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) ---- */
.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: 4px 40px 28px;
    max-width: 1240px;
    margin-left: auto;
    margin-right: auto;
}
@media (max-width: 660px) {
    .dt-day-night {
        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: 660px) {
    .e-con-inner:has(> .elementor-widget-dt-location-card),
    .e-con:has(> .elementor-widget-dt-location-card) {
        grid-template-columns: minmax(0, 400px) !important;
        padding-inline: 20px;
    }
}

/* ===================================================================
   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. */
.dt-map-popup {
    display: block;
    font-family: var(--dt-font-mono);
    color: var(--dt-black);
    text-decoration: none;
}
.dt-map-popup__title {
    display: block;
    font-size: 15px;
    color: var(--dt-dark-green);
}
.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;
}
/* The short hand-drawn arrows shouldn't slide on hover like the long one. */
.dt-arrow-link--arrow-down:hover .dt-arrow-link__icon,
.dt-arrow-link--arrow-diag:hover .dt-arrow-link__icon {
    transform: none;
}

/* ===================================================================
   Locations footer: hide the legal row (payment icons + cashless
   disclaimer) and its divider — not shown on this page per design.
   =================================================================== */
body.page-locations .dt-site-footer__row--meta {
    display: none;
}

/* ===================================================================
   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);
    text-transform: uppercase; /* Figma renders the tagline uppercase */
    color: var(--dt-white);
    white-space: pre-line;
}
/* "Shop the store" CTA is uppercase in the Figma (scoped so the shared
   arrow-link stays mixed-case elsewhere). */
.dt-cross-promo .dt-arrow-link {
    text-transform: uppercase;
}
.dt-cross-promo__body {
    margin: 0 0 24px;
    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 (transform + color only — no shadows) ------- */
    .dt-anim-ready .dt-location-card:hover,
    .dt-anim-ready .dt-product-card:hover,
    .dt-anim-ready .dt-ig-tile:hover {
        transform: translateY(-4px);
    }

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

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