/* FOUNDER RULE (2026-05-03): OVERRIDE/HARDCODE INVENTORY
   ===============================================================
   Anything in this file that hardcodes, !important-overrides, or
   pins admin-controlled values must be listed here so future passes
   don't re-introduce a regression Founder already fought through.

   Active overrides this stylesheet maintains (as of 2026-05-03):
   - .tk-logo-shell: transition removed (was 0.12s transform animator).
     Final visible position is the CSS-var consumer; admin slider
     drags it live without animation.
   - .tk-header-row: pinned min-height = canonical row-height var × 2,
     align-items: start. Stops async content (menu items, category
     pills) from growing the row and re-vertical-centering children.
     The admin-driven brand offset Y still controls the brand block;
     align-items: start just stops content-driven drift.
   - .tk-card-art: float animation now applies whenever animations
     enabled (was gated behind a legacy data attribute).
   - body[data-tk-legal-banner-acked-pre]: hides the prerendered
     legal banner when sessionStorage shows the user already acked
     the current legalVersion.
   - REMOVED 2026-05-03: brandLockoutStyle inline `<style>` with
     `!important` transform on .tk-logo-shell. It was overwriting the
     admin slider preview — the admin appeared broken because the
     `!important` rule beat the CSS-var path. Removed entirely.
   - .tk-logo-shell, .tk-city, .tk-header-actions: transform composes
     --tk-header-equalize-shift-x with the existing offset/translate
     vars. The shift is computed by wireHeaderInnerGapEqualizer in
     run.js and equalizes SEARCH→brand-block vs SEARCH→actions visible
     gaps. Default 0px, so pre-paint state is unchanged.
   - :root[data-theme="dark"] .tk-platform-map-tiles:not([data-tk-google-maps-active]) img:
     CSS filter (invert + hue-rotate 180°) makes raster/OSM tiles
     dark in dark mode. Google Maps provider is excluded because
     it has its own dark Map ID / styles path in run.js.
   - :root[data-theme="dark"] dark-mode override block (after the
     map tile filter rule above): retargets hardcoded white/cream
     backgrounds onto the theme token map. Specifically:
     .tk-product-3d-stage / .tk-product-3d-fallback-image (was
     hardcoded #ffffff → #f5f3ec), .tk-tokebot, .tk-account-link,
     plus the homepage map's bottom fade and the header's bottom
     fade. Founder reports these "stayed white in dark mode" — they
     now track --tk-paper / --tk-bg / --tk-header-fade-strong.
   - 2026-05-03 BULK REBRAND: every hardcoded green hex (var(--tk-leaf),
     #1f3d2c, #7bcf8a) now reads `var(--tk-leaf, #3a8f5a)` etc., and
     every rgba green (rgba(58,143,90,X), rgba(31,61,44,X),
     rgba(123,207,138,X)) now reads `color-mix(in srgb, var(--tk-leaf)
     Y%, transparent)`. Token DEFINITIONS at :root remain raw hex
     (--tk-leaf: var(--tk-leaf)) so the brand resolver's inline <style
     data-tk-brand-theme="netbics"> block can override --tk-leaf to
     blue (#3370c7) and ALL CSS rules pick that up. Founder rule:
     "GO OVER ALL OF TIKTOKE CSS, OVERRIDES, ETC -- AND MAKE SURE
     ON TIKTOK THAT IT POINTS ALL TO THEME COLORS. NO GREEN
     ANYWHERE ON NETBICS".
   - .tk-map-marker[data-marker-kind="customer"]: pinned to map-div
     center (left:50%; top:50%; translate(-50%,-50%) !important) so
     the customer pin stays SCREEN-FIXED while the map drags freely.
     The reproject loop in run.js excludes data-marker-kind="customer"
     so dragging the map no longer carries the customer pin away
     from the visible area. Store/business pins still reproject.

   If you ADD a new !important override or hardcode, append a line
   above describing what it overrides and why.
   ===============================================================
*/

/* /demo TIKTOKE cannabis homepage — Style 1 (light, modern, sleek)
   Pass origin: #passes.txt CANNABIS PLATFORM TIKTOKE FRONTEND DESIGN PASS,
   PHASE 2 NETFLIX HOMEPAGE ROWS, plus Founder direct (2026-04-28) "/demo
   mini-scope". Colors stay in a clean cannabis-green + warm-paper palette.
   No copyrighted imagery — all tiles use SVG/CSS gradients generated in
   demo.js. */

:root {
  /* Founder HARD CORRECTION 2026-05-03 — founder rule (verbatim):
     "use '#e3e2e0' as the main color background (make sure its in
     theme background). apply across the board of all sites".
     --tk-bg drives `body { background }` (line ~331) and is the
     fallback for `--page-bg-color` (line ~107). Brands DO NOT
     override --tk-bg in theme-map.json so the same neutral grey
     paints both TikToke and Netbics. Dark mode still overrides to
     --tk-dark-bg via the `:root[data-theme="dark"]` block below. */
  --tk-bg: #e3e2e0;
  --tk-paper: #ffffff;
  --tk-ink: #161613;
  --tk-ink-soft: #4a4a44;
  --tk-muted: #8b897e;
  --tk-line: #e6e1d4;
  --tk-line-strong: #cfc8b6;
  /* Founder HARD CORRECTION 2026-05-03 — TOKEN DEFINITIONS only.
     These are the LIGHT-MODE defaults; the brand-resolver inline
     <style data-tk-brand-theme="..."> block in <head> overrides
     them per host (tiktoke=green, netbics=blue) BEFORE this file
     loads, so on netbics.com --tk-leaf becomes #3370c7. Do NOT
     wrap these in var(--tk-leaf, ...) — that creates a self-
     referencing cycle that defeats the brand override. */
  --tk-leaf: var(--tk-leaf);
  --tk-leaf-light: #7bcf8a;
  --tk-leaf-deep: var(--tk-leaf-deep);
  --tk-dark-default-green: var(--tk-leaf);
  --tk-dark-accent: var(--tk-leaf-deep);
  /* Founder HARD CORRECTION 2026-05-03 (rev 2) — founder rule:
     "second i load in, it says 'what city' for current location,
     and the province at the top is still using a green tint
     around the pill, instead of using theme colors". --tk-leaf-soft
     was hardcoded mint green (#d8ead8). Now derived from --tk-leaf
     via color-mix so the location-current pill (and all other
     leaf-soft consumers) cascades to netbics blue + tiktoke green
     without a hardcoded literal. */
  --tk-leaf-soft: color-mix(in srgb, var(--tk-leaf) 22%, var(--tk-paper));
  --tk-warm: var(--tk-warm);
  --tk-warn: #c9543c;
  --tk-shadow: 0 1px 2px rgba(20, 20, 18, 0.04), 0 8px 28px rgba(20, 20, 18, 0.06);
  --tk-radius: 14px;
  --tk-radius-sm: 10px;
  --tk-radius-lg: 22px;
  --page-bg-color: var(--tk-bg);
  --tk-play-fade-top-height: 60px;
  --tk-play-fade-bottom-height: 0px;
  --tk-play-game-edge-color: #0a0d11;
  --tk-play-frame-mobile-width: 100vw;
  --tk-play-frame-mobile-half-width: 50vw;
  --tk-play-frame-mobile-bottom-radius: 16px;
  --tk-play-frame-mobile-min-height-home: clamp(410px, 74svh, 620px);
  --tk-play-frame-mobile-min-height-order: clamp(450px, 80svh, 700px);
  --tk-font-sans: "Aptos", "SF Pro Display", "Segoe UI Variable", "Segoe UI", system-ui, sans-serif;
  --tk-row-title-color: var(--tk-leaf-deep);
  --tk-row-title-size: 22px;
  --tk-row-description-size: 13px;
  --tk-link-color: var(--tk-leaf-deep);
  --tk-card-radius: 20px;
  --tk-card-shadow: 0 16px 34px color-mix(in srgb, var(--tk-leaf-deep) 8%, transparent);
  --tk-card-hover-shadow: 0 22px 46px color-mix(in srgb, var(--tk-leaf-deep) 13%, transparent);
  --tk-card-border-color: color-mix(in srgb, var(--tk-leaf-deep) 12%, transparent);
  --tk-card-metric-color: var(--tk-warm);
  --tk-card-art-glow: color-mix(in srgb, var(--tk-leaf) 18%, transparent);
  --tk-row-track-gap: 12px;
  --tk-row-track-gap-mobile: 12px;
  /* Founder LIVE EDIT 2026-05-01: marketplace card idle float — values are
     pre-computed for ~1.25x more activity vs the prior 3px / 3600ms / 1180ms
     baseline, so motion is visible on small mobile cards too. */
  --tk-card-media-float-distance: 4px;
  --tk-card-media-float-duration: 2880ms;
  --tk-card-media-fast-scroll-duration: 944ms;
  /* Founder LIVE EDIT 2026-05-01: header icon dance ~1.2x more active.
     Computed values: duration 2200ms / 1.2 ≈ 1833ms; scale 1.06 grown by
     1.2 ≈ 1.072; mic pulse 1000ms / 1.2 ≈ 833ms. No literal multiplier
     in the source. */
  --tk-activity-pulse-duration: 1833ms;
  --tk-activity-pulse-scale: 1.072;
  --tk-mic-pulse-duration: 833ms;
  --tk-card-media-aspect-ratio: 1 / 1;
  --tk-card-media-depth-shadow: 0 18px 36px color-mix(in srgb, var(--tk-leaf-deep) 18%, transparent);
  --tk-card-body-shelf-width: 92%;
  /* Founder HARD CORRECTION 2026-05-03 (rev 5) — founder iterated:
     "move the carousel titles (and the text under the titles)
     upwards into the image a little closer. NOT TOO MUCH!".
     Tightened from 8px → -6px so the title sits ~6px ABOVE the
     image bottom (a soft overlap, half of the original -18px
     overlap). Subtle, just kisses the artwork. */
  --tk-card-body-shelf-offset: -6px;
  --tk-card-body-shelf-padding: 12px 14px 14px;
  --tk-verified-green: var(--tk-leaf);
  --tk-status-online: var(--tk-leaf, #3a8f5a);
  --tk-status-idle: #c99c3a;
  --tk-status-offline: #8f3a32;
  --tk-status-offline-soft: #7f8275;
  --tk-status-glow-online: color-mix(in srgb, var(--tk-leaf) 42%, transparent);
  --tk-status-glow-idle: rgba(201, 156, 58, 0.4);
  --tk-status-glow-offline: rgba(143, 58, 50, 0.34);
  --tk-platform-map-height-desktop: clamp(260px, 32vw, 360px);
  --tk-platform-map-height-mobile: clamp(240px, 68vw, 320px);
  --tk-platform-map-active-order-height-desktop: clamp(182px, 22.4vw, 252px);
  --tk-platform-map-active-order-height-mobile: clamp(168px, 47.6vw, 224px);
  --tk-platform-map-active-order-max-width: var(--tk-content-width);
  --tk-mobile-active-order-top-offset: -8px;
  --tk-platform-map-order-height-desktop: clamp(260px, 32vw, 360px);
  --tk-platform-map-order-height-mobile: clamp(240px, 68vw, 320px);
  --tk-visual-viewport-height: 100vh;
  --visual-vh: 1vh;
  --tk-platform-map-homepage-height-desktop: calc(var(--visual-vh, 1vh) * 50);
  --tk-platform-map-homepage-height-mobile: calc(var(--visual-vh, 1vh) * 50);
  --tk-platform-map-top-fade-height: 58px;
  --tk-platform-map-zoom: 1;
  --tk-platform-map-zoom-overscan: 18%;
  --tk-mobile-header-height: 124px;
  --tk-content-width: min(1180px, calc(100vw - 28px));
  --tk-map-hero-article-width: min(80vw, 1120px);
  --tk-article-card-width: 460px;
  --tk-article-card-height: 192px;
  --tk-article-card-aspect: 12 / 5;
  --tk-article-card-radius: 24px;
  --tk-article-card-gap: 14px;
  --tk-article-card-scale: 1;
  --tk-map-hero-article-overlap: clamp(150px, 18vw, 230px);
  --tk-map-hero-article-overlap-mobile: clamp(150px, 48vw, 230px);
  --tk-map-hero-article-mobile-scale: 0.8;
  /* Founder Pass 10.6.x 2026-05-04 — founder rule (verbatim):
     "i updated the homepage background recently. use the same color
     for the menu too !". The menu surface now tracks --tk-bg
     (#e3e2e0) instead of the legacy cream var(--tk-paper) so the desktop
     header, mobile drawer, and category bar fade all sit on the
     same neutral grey as the page body. Alpha levels (.92 / .96)
     preserve the prior subtle backdrop translucency. */
  --tk-header-surface: color-mix(in srgb, var(--tk-bg) 92%, transparent);
  --tk-mobile-header-panel-bg: color-mix(in srgb, var(--tk-bg) 96%, transparent);
  --tk-mobile-header-bottom-fade-height: 30px;
  --tk-mobile-header-bottom-fade-overlap: 18px;
  --tk-header-map-fade-height: 46px;
  --tk-header-fade-strong: color-mix(in srgb, var(--tk-header-surface) 100%, transparent);
  --tk-header-fade-mid: color-mix(in srgb, var(--tk-header-surface) 62%, transparent);
  --tk-header-fade-soft: color-mix(in srgb, var(--tk-header-surface) 38%, transparent);
  --theme-dark-green: var(--tk-leaf-deep);
  --tk-category-menu-desktop-width: 90%;
  --tk-category-menu-desktop-max-width: 90%;
  /* Founder LIVE EDIT 2026-05-01 (HEADER SEAM ALIGNMENT FIX —
     remove visible gap between white header and green category
     bar): the prior 0px gap let the search bar's bottom box-shadow
     bleed visibly between the rounded search bar and the green
     category bar's flat top — Founder: "visible seam where white
     header ENDS before green category bar begins." Negative -10px
     pulls the green bar UP so it overlaps the search bar's shadow
     zone, making the cream→green transition land directly under
     the search bar's visual bottom edge with no exposed cream
     strip in between. The search bar still sits visually on top
     because its z-index (default auto inside grid) wins where
     they overlap. */
  --tk-category-menu-desktop-gap: -10px;
  --tk-category-menu-edge-fade-width: 56px;
  --tk-category-menu-bottom-fade-height: 13px;
  --tk-category-menu-edge-fade-color: transparent;
  --tk-category-menu-desktop-bg: color-mix(in srgb, var(--tk-leaf-deep) 92%, transparent);
  --desktop-category-font-size: 10px;
  --desktop-category-item-gap: 0px;
  --desktop-category-item-padding-x: 6px;
  --desktop-category-item-padding-y: 5px;
  --tk-category-active-glow-bg: radial-gradient(circle at 50% 50%, rgba(255, 255, 255, 0.34), rgba(255, 255, 255, 0.16) 42%, transparent 72%);
  --tk-category-active-glow-inset: -7px -12px;
  --tk-desktop-brand-block-width: clamp(260px, 22vw, 340px);
  --tk-desktop-brand-scale: 1.28;
  --tk-desktop-brand-logo-gap: 10px;
  --tk-desktop-brand-mark-size: 44px;
  --tk-desktop-brand-word-size: 26px;
  /* Founder live edit 2026-04-30: mobile-only logo size and vertical-alignment
     so the mobile logo never inherits the larger desktop mark size. The
     missed-items pass introduced --tk-desktop-brand-mark-size as the only
     source of truth for .tk-logo-mark, which made mobile inherit 44px and
     dip below the 34px icon row. Restoring 30px keeps the logo centered
     in the top icon row alongside hamburger/heart/location/activity/cart. */
  --tk-mobile-brand-mark-size: 30px;
  --tk-mobile-brand-logo-offset-y: 0px;
  --tk-mobile-brand-logo-vertical-align: center;
  --tk-desktop-brand-vertical-align: 6px;
  --tk-desktop-location-offset: 0px;
  --tk-desktop-location-scale: 1.06;
  --desktop-location-pill-height: 22px;
  --desktop-location-pill-font-size: 10px;
  --desktop-location-pill-padding-x: 7px;
  --desktop-location-pill-gap: 4px;
  /* Founder LIVE EDIT 2026-05-01 (desktop location pill icon shrink):
     "make the location icon in the desktop menu (that's inside the
     white toggle) 90% the size it is right now. dont hardcode 90%
     into the settings, but do the math and update it."
     Math: prior value 12px × 0.9 = 10.8px. Setting to 10.8px so the
     SVG inside .tk-city-btn renders at the new resolved size with
     no runtime multiplier. */
  --desktop-location-pill-icon-size: 10.8px;
  --tk-mobile-search-category-group-margin-top: 34px;
  --mobile-header-icon-control-size: 34px;
  --mobile-header-icons-to-search-gap: 8px;
  /* Founder LIVE EDIT 2026-05-01 (REVERT mobile green menu UP —
     Founder: "YOU JUST MOVED THE GREEN MENU UP ON MOBILE, MOVE
     THAT BACK!!"): restored the prior calc that derived the gap
     from --mobile-header-icons-to-search-gap (8/2 = 4px). The
     -8px override applied during the earlier seam-alignment pass
     pushed the green bar up over the search bar; that worked on
     desktop but on mobile the header layout already accommodates
     the original gap and the change disturbed the mobile look. */
  --mobile-search-to-categories-gap: calc(var(--mobile-header-icons-to-search-gap) / 2);
  --mobile-header-search-top-offset: 42px;
  --mobile-header-category-attach-offset: 0px;
  /* Founder LIVE EDIT 2026-05-01 (MOBILE GREEN CATEGORY BAR WIDTH
     EXPANSION): Founder's exact spec: "Extend the usable width of
     the category bar to approximately HALF the distance between
     left edge of 'All' → left side of search icon, AND rightmost
     category item → right side of microphone icon."
     Changed:
       width 90% → 100% so the bar spans the same horizontal bounds
         as the search bar above it (mobile search has flex 0 0 100%).
       padding-x 56px → 24px (approximately half) so visible items
         start much closer to the search/mic icons rather than
         being inset way inside the search bar's bounds.
     Edge fade is still applied via mask-image but with the smaller
     padding the visible-region/fade-region balance becomes
     | mostly-visible | small-fade |  per Founder's mock. */
  --tk-mobile-category-bar-width: 100%;
  --tk-mobile-category-bar-max-width: 720px;
  /* Founder PASS 54 2026-05-01 (tablet category-bar width slider): tablet
     token sits between mobile (≤720px) and desktop (≥981px). The mobile
     @media block at line ~8520 caps the bar at --tk-mobile-category-bar-
     max-width by default; a nested @media (min-width: 721px) override
     swaps to --tk-tablet-category-bar-max-width on tablet widths so
     iPad-class viewports get their own tuned width without touching the
     phone or desktop tokens. */
  --tk-tablet-category-bar-max-width: 880px;
  --tk-mobile-category-bar-padding-x: 24px;
  --tk-mobile-category-bar-padding-y: 4px;
  --tk-mobile-category-bottom-fade-height: 0px;
  --mobile-category-font-size: 10px;
  --mobile-category-item-gap: 0px;
  --mobile-category-item-padding-x: 7px;
  --mobile-category-item-padding-y: 6px;
  --mobile-category-text-color: rgba(255, 255, 255, 0.88);
  --mobile-category-active-text-color: #fff;
  --tk-mobile-header-map-fade-height: 72px;
  --tk-settings-max-width: 820px;
  --tk-settings-card-gap: 12px;
  --tk-settings-card-padding: 16px 18px;
  --tk-settings-card-radius: 18px;
  --tk-settings-control-width: min(260px, 34vw);
  --tk-settings-card-bg: rgba(255, 255, 255, 0.78);
  --tk-settings-card-bg-dark: rgba(31, 33, 29, 0.94);
  --tk-settings-card-border: color-mix(in srgb, var(--tk-leaf-deep) 11%, transparent);
  --tk-settings-card-border-dark: rgba(247, 243, 232, 0.14);
  --tk-settings-card-shadow: 0 16px 34px color-mix(in srgb, var(--tk-leaf-deep) 7%, transparent);
  --tk-settings-card-shadow-dark: 0 16px 34px rgba(0, 0, 0, 0.28);
  --tk-spin-wheel-close-color: var(--tk-leaf-deep);
  --tk-spin-wheel-close-bg: color-mix(in srgb, var(--tk-leaf-deep) 10%, transparent);
  --tk-spin-wheel-close-border: color-mix(in srgb, var(--tk-leaf-deep) 12%, transparent);
  --tk-spin-wheel-close-hover-color: var(--tk-ink);
  --tk-spin-wheel-close-hover-bg: color-mix(in srgb, var(--tk-leaf) 18%, transparent);
  --tk-spin-wheel-close-focus-shadow: 0 0 0 3px color-mix(in srgb, var(--tk-leaf) 22%, transparent);
  --tk-homepage-section-pad: clamp(16px, 3vw, 28px);
}

* { box-sizing: border-box; }
html, body {
  /* Founder LIVE EDIT BLOCK 2026-05-01 (desktop sticky header was broken
     by overflow-x: hidden on body — that creates a body-level scroll
     container which traps position:sticky descendants, so the header
     scrolled with content instead of sticking to top:0). Switched to
     overflow-x: clip — clips horizontal overflow without turning body
     into a scroll container. The viewport remains the scroll context,
     so .tk-header's position:sticky now sticks at top:0 as designed.
     Supported in all modern browsers (Chrome 90+, Safari 16+, Firefox
     81+). The fallback for legacy browsers degrades to a non-clipped
     horizontal scrollbar — minor cosmetic, not a functional break. */
  margin: 0; padding: 0; min-height: 100%; overflow-x: clip; background: var(--tk-bg); color: var(--tk-ink); font: 15px/1.5 var(--tk-font-sans);
}
body { -webkit-font-smoothing: antialiased; }

:root[data-theme="dark"] {
  /* Founder live edit 2026-04-29: dark mode colors are sourced from
     config/site/homepage.json -> theme.darkMode. These fallbacks only keep
     first paint readable before JSON applies; do not add one-off dark color
     overrides outside the token map in demo.js. */
  /* Founder HARD CORRECTION 2026-05-03 — founder rule "DARK GRAY NOT
     BLACK". Fallbacks raised from #121212 (essentially black) to
     #2a2a2a (clear dark gray). Header surface + fade tokens follow
     the same hue at rgba(42,42,42,*). The JSON token map at
     homepage.json#theme.darkMode mirrors these values; CSS fallbacks
     only matter for the first frame before JSON applies. */
  --tk-bg: var(--tk-dark-bg, #2a2a2a);
  --tk-paper: var(--tk-dark-paper, #353535);
  --tk-paper-strong: var(--tk-dark-paper-strong, #404040);
  --tk-ink: var(--tk-dark-ink, #f7f3e8);
  --tk-ink-soft: var(--tk-dark-ink-soft, #d8d0bf);
  --tk-muted: var(--tk-dark-muted, #b2aa9a);
  --tk-line: var(--tk-dark-line, rgba(247, 243, 232, 0.14));
  --tk-header-surface: var(--tk-dark-header-surface, rgba(42, 42, 42, 0.96));
  --tk-mobile-header-panel-bg: var(--tk-dark-header-surface, rgba(42, 42, 42, 0.96));
  --tk-header-fade-strong: var(--tk-dark-header-fade-strong, rgba(42, 42, 42, 0.98));
  --tk-header-fade-mid: var(--tk-dark-header-fade-mid, rgba(42, 42, 42, 0.7));
  --tk-header-fade-soft: var(--tk-dark-header-fade-soft, rgba(42, 42, 42, 0.32));
  --tk-card-border-color: var(--tk-dark-card-border-color, rgba(247, 243, 232, 0.14));
  --tk-card-shadow: var(--tk-dark-card-shadow, 0 18px 38px rgba(0, 0, 0, 0.34));
  --tk-card-hover-shadow: var(--tk-dark-card-hover-shadow, 0 22px 46px rgba(0, 0, 0, 0.42));
  /* Founder live edit 2026-04-29: dark mode makes regular green the default
     readable green. Dark green remains available only through
     --theme-dark-green / --tk-dark-accent for explicit deep backgrounds. */
  --tk-leaf-deep: var(--tk-dark-default-green, var(--tk-leaf));
  --theme-dark-green: var(--tk-dark-accent, var(--tk-leaf-deep, #1f3d2c));
  --tk-row-title-color: var(--tk-dark-default-green, var(--tk-leaf));
  --tk-leaf-soft: var(--tk-dark-leaf-soft, color-mix(in srgb, var(--tk-leaf) 16%, transparent));
  --tk-link-color: var(--tk-dark-link-color, var(--tk-dark-default-green, var(--tk-leaf)));
  --tk-card-art-glow: var(--tk-dark-glow-soft, color-mix(in srgb, var(--tk-leaf) 16%, transparent));
  --tk-spin-wheel-close-color: var(--tk-dark-spin-wheel-close-color, var(--tk-ink));
  --tk-spin-wheel-close-bg: var(--tk-dark-spin-wheel-close-bg, rgba(247, 243, 232, 0.13));
  --tk-spin-wheel-close-border: var(--tk-dark-spin-wheel-close-border, rgba(247, 243, 232, 0.26));
  --tk-spin-wheel-close-hover-bg: var(--tk-dark-spin-wheel-close-hover-bg, color-mix(in srgb, var(--tk-leaf-light) 24%, transparent));
  --tk-spin-wheel-close-focus-shadow: var(--tk-dark-spin-wheel-close-focus-shadow, 0 0 0 3px color-mix(in srgb, var(--tk-leaf-light) 34%, transparent));
}

:root[data-theme="dark"] .tk-detail-shell,
:root[data-theme="dark"] .tk-settings-row,
:root[data-theme="dark"] .tk-cart-drawer,
:root[data-theme="dark"] .tk-mobile-drawer,
:root[data-theme="dark"] .tk-notifications-popover,
:root[data-theme="dark"] .tk-signin-card {
  background: var(--tk-paper);
  border-color: var(--tk-line);
  color: var(--tk-ink);
}

:root[data-theme="dark"] .tk-account-panel {
  background: var(--tk-account-panel-background-dark, var(--tk-paper));
  box-shadow: var(--tk-account-panel-shadow-dark, none);
  color: var(--tk-ink);
}
:root[data-theme="dark"] .tk-account-panel[open] {
  background: var(--tk-account-panel-background-open-dark, radial-gradient(circle at 96% 12%, var(--tk-dark-glow-soft, color-mix(in srgb, var(--tk-leaf) 16%, transparent)), transparent 28%), var(--tk-paper-strong));
}

body[data-tk-animations="off"] *,
body[data-tk-animations="off"] *::before,
body[data-tk-animations="off"] *::after {
  animation: none !important;
  transition-duration: 0.001ms !important;
  transition-delay: 0ms !important;
  scroll-behavior: auto !important;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation: none !important;
    transition-duration: 0.001ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }
}

a { color: var(--tk-link-color); text-decoration: none; }
/* Founder LIVE EDIT 2026-05-01: site-wide blue → leaf safety net. Any
   element that resolves to a literal blue value gets remapped to the
   regular leaf green so accidental UA defaults / vendor styles never
   leak blue into the green palette. */
.tk-page [style*="color: blue"],
.tk-page [style*="color:#00f"],
.tk-page [style*="color: #00f"] {
  color: var(--tk-leaf) !important;
}
.tk-page :link, .tk-page :visited { color: var(--tk-link-color); }
/* Founder emergency live edit 2026-04-29: demo navigation, category labels,
   mobile drawer links, and card anchors must never show browser underlines.
   Active/hover/focus states use color, weight, or background only. */
.tk-page :where(a, a:hover, a:focus, a:focus-visible, a:active, nav a, nav a:hover, nav a:focus, .tk-main-menu-link, .tk-main-menu-link:hover, .tk-main-menu-link:focus, .tk-cat, .tk-cat:hover, .tk-cat:focus, .tk-mobile-drawer-link, .tk-mobile-drawer-link:hover, .tk-mobile-drawer-link:focus, .tk-map-article-card, .tk-in-page-ad-card, .tk-card, .tk-order-view, .tk-mobile-account-open, .tk-icon-action) {
  text-decoration: none;
  text-decoration-line: none;
}

.tk-icon { width: 18px; height: 18px; }
.tk-icon-sm { width: 14px; height: 14px; }

/* =============== HEADER =============== */
.tk-header {
  /* Founder LIVE EDIT BLOCK 2026-05-01 (menu z-index priority): the
     desktop header was at z-index: 30, which let any page content
     positioned above 30 (e.g. preview pin at 18, but more importantly
     drag-mounted overlays) scroll over it. Bumped to 100 so the menu
     stays above ALL homepage content while still sitting BELOW modal
     dialogs (z-index 140) and the founder admin pill (z-index 43).
     Founder LIVE EDIT 2026-05-01 (FIRST VISIT STACK ORDER FIX —
     STRICT Z-INDEX HIERARCHY): Founder's exact mandate:
       Location Picker  9999
       Age Check        9000
       Other popups     8500
       Privacy Banner   5000
       Menu / Header    4000   ← this rule
       Page content     default
     Header bumped from 100 to 4000 so it sits ABOVE all page content
     but BELOW the privacy banner (5000), spin wheel popup (8500),
     age check (9000), and location picker (9999). */
  position: sticky; top: 0; z-index: 4000;
  background: var(--tk-header-surface);
  backdrop-filter: saturate(180%) blur(14px);
  -webkit-backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 0;
}
/* Founder LIVE EDIT 2026-04-30 (one menu, every route): the header
   styling and bottom-fade were previously scoped to
   body[data-tk-route-type="homepage"], so the Account page (and every
   other non-homepage route) rendered the same DOM with a different
   look — visible cutoff line, no fade. Founder's directive: "ALL MENUS
   TO POINT TO where THE HOMEPAGE MENU points to ... SAME SETTINGS,
   EFFECT, ETC. EVERYTHING." Dropping the route prefix makes these
   rules apply globally on the .tk-header element, which is the same
   sticky header DOM on every page. The route-scoped homepage rules
   for non-header surfaces (.tk-main, .tk-homepage-rows, etc.) stay
   route-gated; only the actual top navigation chrome is unified. */
.tk-header {
  box-shadow: none;
}
.tk-header::after {
  /* Founder LIVE EDIT BLOCK 2026-05-01 (same fade on desktop as mobile —
     just the bottom line of the white menu) + Founder LIVE EDIT
     2026-04-30 (one menu, every route): single ::after extension sits
     BELOW the header bottom edge in the page content area, fading
     from the cream header surface to transparent across the configured
     height. Header itself stays fully solid (logo, nav, search, search
     bar, location pill all opaque — no menu transparency). The
     2026-04-30 follow-up removes the body[data-tk-route-type="homepage"]
     prefix so the fade renders on Account, Order, Store, Product,
     Favorites, Settings, Digital — every route uses the same
     --tk-header-map-fade-height var (set in JSON via
     header.categoryMenuLayout.desktopHeaderFadeHeight). The mobile
     rule inside @media (max-width: 980px) still overrides with
     --tk-mobile-header-bottom-fade-height; that rule is also unscoped
     below for the same reason. */
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  height: var(--tk-header-map-fade-height, 46px);
  z-index: 0;
  pointer-events: none;
  background: linear-gradient(180deg, var(--tk-header-surface) 0%, transparent 100%);
}
.tk-header-row {
  /* Founder revert 2026-05-01: the height-lock attempt from the Claude
     geometry audit (min-height/height/box-sizing: content-box) broke
     the desktop menu layout in production. Reverted to the original
     content-driven row height; logo first-paint correctness (sizes
     injected from logo-geometry.json before paint) still keeps the
     no-flash behavior, just without the row-height clamp.
     Founder LIVE EDIT BLOCK 2026-04-30 (desktop header top space): the
     padding-top is now JSON-driven via --tk-desktop-header-top-space
     (header.desktopHeaderTopSpace) so Founder can adjust the gap between
     the very top of the screen and the row containing Delivery / Stores
     / etc. without editing CSS.
     Founder MASTER STORE/HEADER pass 2026-05-03: equal-distance
     invariant. The base symmetric row padding is preserved
     (clamp(16px,3vw,28px) on both sides → Y1==Y2 outer margins). The
     responsive controller in run.js (wireHeaderGeometry) measures
     LEFT_GROUP and RIGHT_GROUP widths and writes
     --tk-header-row-balance-left / --tk-header-row-balance-right onto
     this row so the centered nav/search column lands viewport-centered
     even when the right icon cluster is wider than brand+city. The
     controller leaves both vars at 0px below the tablet breakpoint so
     the existing mobile layout is untouched. */
  max-width: 1320px; margin: 0 auto;
  /* Founder HARD CORRECTION 2026-05-03 — the
     'BRAND BLOCK + RIGHT ICON CLUSTER OFFSET TO CENTER' slider writes
     --tk-header-outer-cluster-center-gap. When set to a px value
     (e.g. 60px), both the left padding (pushing the brand block right)
     AND the right padding (pushing the icon cluster left) grow by
     that amount. Result: the brand block + icon cluster move inward
     symmetrically, and the centered menu/search column gets more
     visual breathing room from both edges. 'auto' (default) =
     0 extra padding. */
  --tk-header-outer-cluster-center-gap-resolved: var(--tk-header-outer-cluster-center-gap, 0px);
  padding: var(--tk-desktop-header-top-space, 14px)
    calc(clamp(16px, 3vw, 28px) + var(--tk-header-outer-cluster-center-gap-resolved, 0px) + var(--tk-header-row-balance-right, 0px))
    14px
    calc(clamp(16px, 3vw, 28px) + var(--tk-header-outer-cluster-center-gap-resolved, 0px) + var(--tk-header-row-balance-left, 0px));
  display: grid;
  grid-template-columns: auto auto 1fr auto;
  gap: 14px; align-items: center;
  /* Founder HARD CORRECTION 2026-05-03 (REVERTED 2026-05-03): the
     min-height + align-items: start I added broke the visible
     position of the green/category menu bar (categories sat at the
     TOP of a 128px-pinned row instead of centered). Reverted both.
     The original align-items: center is restored. The 18px logo
     shift on async content growth will be addressed by reserving
     content rows differently (server-rendered category pills) in a
     future pass — NOT by changing align-items or pinning header row
     height. */
}
@media (max-width: 920px) {
  .tk-header-row { grid-template-columns: auto 1fr auto; }
  .tk-city { grid-column: 1 / -1; order: 4; }
}
@media (max-width: 560px) {
  .tk-header-row { grid-template-columns: 1fr auto; gap: 10px; }
  .tk-search { grid-column: 1 / -1; order: 3; }
  .tk-header-actions .tk-pill-ghost span { display: none; }
}

.tk-logo-shell {
  /* Founder LIVE EDIT 2026-04-30 (single-global-menu pass — logo Y-axis
     bug fix): the JS at demo.js:8557-8562 already writes
     --tk-desktop-brand-logo-offset-x and --tk-desktop-brand-logo-offset-y
     to documentElement on every slider input, but the CSS rule that
     CONSUMED those vars was removed in a prior "broken-menu" revert.
     That's why Founder reported "Y-axis setting currently does nothing."
     Restoring the consumer via transform: translate() — translate doesn't
     affect document flow, so the menu cannot be pushed and the logo
     column max-width still caps. Same pattern as .tk-mobile-logo-shell at
     line 7527-7528 which works correctly on mobile. The cap stays
     JSON-driven via --tk-desktop-logo-shell-max-width (default 220px).
     The logo-mark + word can still scale down inside this cap; the cap
     only limits how WIDE the logo column gets. */
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
  max-width: var(--tk-desktop-logo-shell-max-width, 220px);
  flex: 0 0 auto;
  transform: translate(
    var(--tk-desktop-brand-logo-offset-x, 0px),
    var(--tk-desktop-brand-logo-offset-y, 0px)
  );
  /* Founder HARD CORRECTION 2026-05-03 — kill the visible transform
     transition. The founder reports the logo "still moves" on every
     refresh. Live Playwright reproduction (incognito-logo-movement-
     repro.mjs) measured: logoShell dy=18px, dx=31.14px between t=0ms
     and t=394ms on www.tiktoke.app desktop. Root cause: the prepaint
     boot script sets --tk-desktop-brand-logo-offset-x/y on
     documentElement, but a downstream config-apply path on this
     particular alias overwrites them after first paint, and this
     transition animates the diff over 120ms. Removing the transition
     means any var change is an instant snap — no visible motion
     between frames. The element's final position still comes from
     canonical JSON. NO CSS transition controls placement. */
}
.tk-logo {
  display: inline-flex; align-items: center; gap: 10px;
  text-decoration: none; color: var(--tk-ink);
}
.tk-logo-mark {
  /* Founder missed-items pass 2026-04-30 (item 7) + Claude geometry audit
     fix #1 2026-04-30: the var fallback used to be 54px which caused a
     visible flash on first paint (54 → 44) when the boot CSS var hadn't
     resolved yet. The fallback now equals the canonical desktop mark
     size (44px) so even a missing var renders at the final size — no
     "small then large" flash. The actual size still comes from
     core/cannabis/media/branding/logo-geometry.json injected as a CSS var
     in <head> by sendDemoIndex BEFORE first paint. (Folder relocated
     2026-05-01 — Founder MASTER 3D ASSET PIPELINE EXPANSION PART 1.) */
.tk-product-3d-stage {
  background: linear-gradient(180deg, #ffffff 0%, #f5f3ec 100%);
  border-radius: 14px;
  overflow: hidden;
  box-shadow: 0 6px 24px color-mix(in srgb, var(--tk-leaf-deep) 6%, transparent), inset 0 0 0 1px color-mix(in srgb, var(--tk-leaf-deep) 4%, transparent);
  position: relative;
}
.tk-product-3d-fallback-image {
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: linear-gradient(180deg, #ffffff 0%, #f5f3ec 100%);
}
  width: var(--tk-desktop-brand-mark-size, 44px);
  height: var(--tk-desktop-brand-mark-size, 44px);
  aspect-ratio: 1 / 1;
  display: block;
  object-fit: contain;
}
.tk-logo-word { font-weight: 800; letter-spacing: 0.16em; font-size: 18px; color: var(--tk-leaf-deep); }
.tk-logo-tag {
  display: none;
}
.tk-logo-picker-toggle {
  width: 24px;
  height: 24px;
  border: 0;
  background: transparent;
  color: var(--tk-leaf-deep);
  display: inline-grid;
  place-items: center;
  padding: 0;
  cursor: pointer;
}
.tk-logo-picker-toggle[hidden] { display: none !important; }
.tk-logo-picker {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  z-index: 60;
  width: min(320px, calc(100vw - 32px));
  padding: 10px;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  background: rgba(255, 255, 255, 0.98);
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 14%, transparent);
  border-radius: 18px;
  box-shadow: 0 20px 50px color-mix(in srgb, var(--tk-leaf-deep) 16%, transparent);
}
.tk-logo-picker[hidden] { display: none !important; }
.tk-logo-option {
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 12%, transparent);
  background: color-mix(in srgb, var(--tk-paper) 72%, transparent);
  color: var(--tk-leaf-deep);
  border-radius: 14px;
  padding: 8px;
  display: grid;
  justify-items: center;
  gap: 5px;
  font: inherit;
  font-size: 11px;
  font-weight: 800;
  cursor: pointer;
}
.tk-logo-option img {
  width: 42px;
  height: 42px;
  object-fit: contain;
  display: block;
}
.tk-logo-option[data-active="true"] {
  border-color: var(--tk-leaf);
  background: rgba(216, 234, 216, 0.9);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--tk-leaf) 12%, transparent);
}

.tk-city-btn {
  background: var(--tk-paper); border: 1px solid var(--tk-line); color: var(--tk-ink);
  padding: 8px 12px; border-radius: 999px; cursor: pointer;
  display: inline-flex; align-items: center; gap: 8px; font: inherit; font-size: 13px;
  box-shadow: var(--tk-shadow);
  transition: border-color .15s, transform .12s;
}
.tk-city-btn:hover { border-color: var(--tk-leaf); transform: translateY(-1px); }
.tk-city-btn strong { font-weight: 700; }

.tk-search {
  background: var(--tk-paper); border: 1px solid var(--tk-line); border-radius: 999px;
  display: flex; align-items: center; gap: 10px; padding: 8px 14px;
  /* Founder Pass 10.6.x 2026-05-04 — founder rule (verbatim): "Search
     bar height must persist." --tk-search-bar-height is admin-driven
     (data-tk-search-bar-height slider) and persists through
     headerMenuLayout.searchBarHeightPx → homepage.json#header.search
     BarHeightPx → applyHeaderConfig CSS var. min-height clamps the
     bar so admin changes always grow the bar (padding still allows
     content to fit). Default 0px = honour padding only (legacy). */
  min-height: var(--tk-search-bar-height, 0px);
  box-shadow: var(--tk-shadow);
  transition: border-color .15s, box-shadow .15s;
  position: relative;
}
.tk-search:focus-within { border-color: var(--tk-leaf); box-shadow: 0 0 0 4px color-mix(in srgb, var(--tk-leaf) 14%, transparent); }
.tk-search input {
  /* Founder live edit 2026-04-30 (item 2): search text is centered visually
     in the bar on both desktop and mobile, controlled by JSON
     search_input_align via the --tk-search-input-align CSS var. */
  flex: 1; border: 0; outline: 0; background: transparent; font: inherit; font-size: 14px;
  color: var(--tk-ink);
  text-align: var(--tk-search-input-align, left);
}
.tk-search input::placeholder { color: var(--tk-muted); text-align: var(--tk-search-input-align, left); }
.tk-search-mic {
  border: 0;
  background: transparent;
  color: var(--tk-leaf-deep);
  padding: 2px;
  width: 28px;
  height: 28px;
  display: inline-grid;
  place-items: center;
  cursor: pointer;
  border-radius: 999px;
  flex: 0 0 auto;
}
.tk-search-mic:hover,
.tk-search-mic[data-listening="true"] {
  color: var(--tk-leaf);
}
.tk-search-mic[data-listening="true"] {
  animation: tkMicPulse var(--tk-mic-pulse-duration, 833ms) ease-in-out infinite;
}
.tk-search-status {
  position: absolute;
  left: 18px;
  top: calc(100% + 6px);
  max-width: min(360px, calc(100vw - 48px));
  color: var(--tk-leaf-deep);
  background: color-mix(in srgb, var(--tk-paper) 94%, transparent);
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 12%, transparent);
  border-radius: 999px;
  box-shadow: 0 10px 20px color-mix(in srgb, var(--tk-leaf-deep) 8%, transparent);
  font-size: 11px;
  font-weight: 750;
  line-height: 1.2;
  padding: 5px 10px;
  pointer-events: none;
  z-index: 3;
}
.tk-search-status:empty { display: none; }
.tk-search-status[data-tone="error"] {
  color: var(--tk-warn);
  border-color: rgba(201, 84, 60, 0.18);
}
.tk-search-results {
  position: absolute;
  z-index: 55;
  left: 0;
  right: 0;
  /* Founder Pass 10.6.x 2026-05-04 — founder rule (verbatim): "add
     to my admin menu options (by brand block/header gemoetry at the
     top): search bar results y value". --tk-search-results-offset-y
     is admin-driven (data-tk-search-results-offset-y slider) and
     defaults to 0px; admin pushes a positive value to drop the
     dropdown lower or a negative value to lift it closer to the
     search bar. */
  top: calc(100% + 9px + var(--tk-search-results-offset-y, 0px));
  display: grid;
  gap: 5px;
  padding: 8px;
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 14%, transparent);
  border-radius: 18px;
  /* Founder Pass 10.6.x 2026-05-04 — founder rule (verbatim): "Dark
     mode search bar is wrong. No white search bar/background/overlay
     pieces are allowed in dark mode." Was rgba(255,255,255,0.98) —
     hardcoded white. Now var(--tk-paper) which is the brand paper
     in light mode and the dark surface (#353535 etc.) in dark mode,
     so the dropdown matches the search bar surface in both themes. */
  background: var(--tk-paper);
  box-shadow: 0 18px 44px color-mix(in srgb, var(--tk-leaf-deep) 16%, transparent);
}
/* Founder Pass 10.6.x 2026-05-04 — founder rule (verbatim):
   "SNAP LOCATION PILL TO CENTER OF LOGO+TITLE does not work. It
   must horizontally center the location pill under the combined
   logo + title group, not just under title text." Earlier
   align-self:center centered the pill VERTICALLY inside its
   parent column. The founder wants HORIZONTAL center under the
   .tk-logo (mark + word) bounding box. Implemented via a runtime
   measurer (wireSnapLocationPillCenter in run.js) that writes
   --tk-snap-location-pill-offset-x; this CSS rule consumes it. */
body[data-tk-snap-location-pill-center="true"] .tk-city {
  margin-top: 0 !important;
  --tk-desktop-location-offset: 0px !important;
  transform: translateX(var(--tk-snap-location-pill-offset-x, 0px)) !important;
}
.tk-search-results[hidden] { display: none !important; }
.tk-search-result {
  border: 0;
  border-radius: 13px;
  padding: 9px 10px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 2px 10px;
  align-items: center;
  background: color-mix(in srgb, var(--tk-paper) 72%, transparent);
  color: var(--tk-ink);
  text-align: left;
  text-decoration: none;
  font: inherit;
  cursor: pointer;
}
.tk-search-result:hover {
  /* Founder Pass 10.6.x 2026-05-04 — was hardcoded TikToke green-
     tinted hover rgba(216,234,216,0.78). Now color-mix on
     --tk-leaf so each brand renders its own hover (TikToke green-
     soft, NetBics red-soft) and dark mode adapts via the brand
     palette injected on :root. */
  background: color-mix(in srgb, var(--tk-leaf) 22%, transparent);
}
.tk-search-result strong { font-size: 13px; }
.tk-search-result span { color: var(--tk-muted); font-size: 11px; }
.tk-search-result em {
  grid-row: 1 / span 2;
  grid-column: 2;
  color: var(--tk-leaf-deep);
  font-size: 10px;
  font-style: normal;
  font-weight: 900;
  text-transform: uppercase;
}
.tk-search-ai {
  background: linear-gradient(135deg, rgba(216, 234, 216, 0.92), rgba(255, 247, 232, 0.92));
}
@keyframes tkMicPulse {
  0%, 100% { transform: scale(1); opacity: 0.78; }
  50% { transform: scale(1.12); opacity: 1; }
}
body[data-tk-performance="slow"] *,
body[data-tk-page-hidden="true"] * {
  animation-duration: 0.001ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: 0.001ms !important;
}
/* Founder LIVE EDIT 2026-05-01: marketplace card idle float + ad/CTA float
   are GPU-cheap (transform: translateY only) and are core UX cues. Carve
   them out of the slow-tier and page-hidden global animation kill so they
   stay visible on real mobile phones. prefers-reduced-motion still
   disables them cleanly through the .tk-card-art @media rule below. */
body[data-tk-performance="slow"] .tk-card-art,
body[data-tk-page-hidden="false"] .tk-card-art {
  animation-duration: var(--tk-card-media-float-duration, 2880ms) !important;
  animation-iteration-count: infinite !important;
}
body[data-tk-performance="slow"] .tk-priority-signup-panel[data-animation="soft-bounce"],
body[data-tk-page-hidden="false"] .tk-priority-signup-panel[data-animation="soft-bounce"] {
  animation-duration: var(--tk-card-media-float-duration, 2880ms) !important;
  animation-iteration-count: infinite !important;
}
body[data-tk-performance="slow"] .tk-in-page-ad-card,
body[data-tk-page-hidden="false"] .tk-in-page-ad-card {
  animation-duration: var(--tk-card-media-float-duration, 2880ms) !important;
  animation-iteration-count: infinite !important;
}
/* Founder LIVE EDIT 2026-05-01: header-icon dance (cart, notifications,
   activity) — keep alive on slow-tier devices too. */
body[data-tk-performance="slow"] .tk-header-actions [data-tk-notifications-toggle] .tk-icon,
body[data-tk-performance="slow"] .tk-pill-cart .tk-icon,
body[data-tk-page-hidden="false"] .tk-header-actions [data-tk-notifications-toggle] .tk-icon,
body[data-tk-page-hidden="false"] .tk-pill-cart .tk-icon {
  animation-duration: var(--tk-activity-pulse-duration, 1833ms) !important;
  animation-iteration-count: infinite !important;
}
body[data-tk-performance="slow"] .tk-search-mic[data-listening="true"],
body[data-tk-page-hidden="false"] .tk-search-mic[data-listening="true"] {
  animation-duration: var(--tk-mic-pulse-duration, 833ms) !important;
  animation-iteration-count: infinite !important;
}

/* Founder PASS 67 2026-05-02 (TokeBot signature presence — slow-tier carve-out):
   the global slow-tier rule kills animation-duration to 1µs. The
   TokeBot presence animation needs its full timing to feel premium,
   so we restore each layer's timing by selector — same defense-in-depth
   pattern pass 49 used for header-icon dance + card art. State attrs
   override these durations from the IDLE base above. */
body[data-tk-performance="slow"] .tk-tbp-orbit,
body[data-tk-page-hidden="false"] .tk-tbp-orbit {
  animation-duration: 6s !important;
  animation-iteration-count: infinite !important;
}
body[data-tk-performance="slow"] .tk-tbp-ribbon,
body[data-tk-page-hidden="false"] .tk-tbp-ribbon {
  animation-duration: 6s !important;
  animation-iteration-count: infinite !important;
}
body[data-tk-performance="slow"] .tk-tbp-glow,
body[data-tk-page-hidden="false"] .tk-tbp-glow {
  animation-duration: 4.6s !important;
  animation-iteration-count: infinite !important;
}
body[data-tk-performance="slow"] .tk-tbp-emblem,
body[data-tk-page-hidden="false"] .tk-tbp-emblem {
  animation-duration: 4.8s !important;
  animation-iteration-count: infinite !important;
}
body[data-tk-performance="slow"] .tk-tbp-ember-orbit,
body[data-tk-page-hidden="false"] .tk-tbp-ember-orbit {
  animation-duration: 5.2s !important;
  animation-iteration-count: infinite !important;
}

.tk-header-actions { display: inline-flex; gap: 10px; align-items: center; }
.tk-header-actions [data-tk-notifications-toggle] .tk-icon,
.tk-pill-cart .tk-icon {
  animation: tkActivityIconPulse var(--tk-activity-pulse-duration, 2200ms) ease-in-out infinite;
  transform-origin: center;
  color: var(--tk-activity-pulse-color-a, currentColor);
}
@keyframes tkActivityIconPulse {
  0%, 100% {
    color: var(--tk-activity-pulse-color-a, currentColor);
    transform: scale(1);
  }
  50% {
    color: var(--tk-activity-pulse-color-b, var(--tk-leaf));
    transform: scale(var(--tk-activity-pulse-scale, 1.06));
  }
}
body[data-tk-animations="off"] .tk-header-actions [data-tk-notifications-toggle] .tk-icon,
body[data-tk-animations="off"] .tk-pill-cart .tk-icon {
  animation: none !important;
}
.tk-mobile-favorites-action { display: none; }
.tk-account-link span,
.tk-logout-link span {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}
.tk-account-link,
.tk-logout-link {
  width: 38px;
  height: 38px;
  padding: 0;
  justify-content: center;
}
.tk-account-link {
  width: 46px;
  height: 46px;
  color: var(--tk-leaf-deep);
  border-color: color-mix(in srgb, var(--tk-leaf-deep) 22%, transparent);
  background: linear-gradient(145deg, rgba(216, 234, 216, 0.96), rgba(255, 255, 255, 0.88));
}
.tk-account-link .tk-icon {
  width: 22px;
  height: 22px;
}
.tk-pill {
  background: var(--tk-paper); border: 1px solid var(--tk-line); color: var(--tk-ink);
  padding: 8px 14px; border-radius: 999px; cursor: pointer;
  display: inline-flex; align-items: center; gap: 8px; font: inherit; font-size: 13px;
  box-shadow: var(--tk-shadow); transition: transform .12s, border-color .15s, background .15s;
}
.tk-pill:hover { transform: translateY(-1px); border-color: var(--tk-leaf); }
.tk-pill-ghost { background: var(--tk-leaf-soft); border-color: transparent; color: var(--tk-leaf-deep); }
.tk-pill-cart { position: relative; padding-right: 16px; }
.tk-cart-count {
  /* Founder LIVE EDIT BLOCK 2026-05-01 (cart badge must never fall under
     the cart icon at iPad/tablet widths): position: absolute pulls the
     badge out of normal flow so the constrained 34×34 pill at narrow
     widths can't push it onto a second row. The pill itself is
     position:relative so the absolute coords resolve relative to it.
     Top-right transform offset keeps the badge sitting on the icon
     corner exactly like the desktop layout. */
  position: absolute;
  top: -2px;
  right: -2px;
  z-index: 2;
  background: var(--tk-leaf); color: #fff; font-size: 11px; font-weight: 700;
  border-radius: 999px; padding: 1px 7px; min-width: 18px; text-align: center;
  pointer-events: none;
}

/* =============== MENU CATEGORIES =============== */
.tk-categories {
  max-width: 1320px; margin: 0 auto;
  padding: 0 clamp(16px, 3vw, 28px) 12px;
  display: flex; flex-wrap: nowrap; gap: 8px;
  overflow-x: auto; scrollbar-width: none;
  /* Founder HARD CORRECTION 2026-05-03: REVERTED min-height: 44px on
     .tk-categories and .tk-categories-shell. The reservation broke
     the green/category menu bar visual. Categories rendering is
     content-driven; the 6px hydration shift on mobile is acceptable
     and will be addressed differently (skeleton placeholders or
     server-rendered category pills) in a future pass. */
}
.tk-categories::-webkit-scrollbar { display: none; }
.tk-cat {
  background: transparent; border: 1px solid var(--tk-line); color: var(--tk-ink-soft);
  border-radius: 999px; padding: 6px 14px; font: inherit; font-size: 13px; cursor: pointer;
  white-space: nowrap; transition: border-color .15s, background .15s, color .15s;
}
.tk-cat:hover { border-color: var(--tk-leaf); color: var(--tk-leaf-deep); }
.tk-cat[data-active="true"] {
  background: transparent;
  border-color: transparent;
  color: var(--tk-leaf-deep);
  box-shadow: none;
}

.tk-menu-scrim {
  position: fixed;
  inset: 0;
  z-index: 44;
  background: rgba(18, 20, 16, 0.34);
  opacity: 0;
  pointer-events: none;
  transition: opacity .18s ease;
}
.tk-menu-scrim:not([hidden]) {
  opacity: 1;
  pointer-events: auto;
}
.tk-mobile-drawer {
  /* Founder LIVE EDIT 2026-05-01 (slide-out menu joins modal tier): the
     mobile drawer was z-index 45, BELOW the sticky header's z-index 100,
     so the slide-out rendered behind the main menu. Founder's directive:
     "joins the age gate and location stuff as being above the menu
     z-index-wise." Age gate is 150 + spin wheel overlay is 140 +
     header is 100; the drawer now matches age-gate at 150 so the
     slide-out covers the header / category bar / search row exactly
     like the age gate does.
     Founder LIVE EDIT 2026-05-01 (FIRST VISIT STACK ORDER FIX —
     drawer in modal tier): bumped from 150 → 9000 to match the new
     Founder hierarchy where the menu/header is at 4000 and the age
     check is at 9000. The drawer is the mobile equivalent of the
     header so it must sit ABOVE the header (z 4000) but at the same
     "modal" tier as Age Check so popups (8500) cannot cover it
     either when both are mounted simultaneously.
     Founder LIVE EDIT 2026-05-01 (pass 51 — drawer offset by privacy
     banner): the drawer's `top` now follows --tk-legal-banner-mobile-h
     so the slide-out starts BELOW the banner instead of covering it.
     The variable is 0px when the banner is dismissed/absent, so the
     drawer falls back to the prior full-height behavior automatically.
     Transition the top change with the same banner-collapse easing so
     the drawer's top edge slides down/up in lockstep with the banner. */
  position: fixed;
  top: var(--tk-legal-banner-mobile-h, 0px);
  bottom: 0;
  left: 0;
  z-index: 9000;
  transition: transform .22s ease,
              top var(--tk-legal-banner-collapse-ms, 280ms) var(--tk-legal-banner-easing, cubic-bezier(0.4, 0, 0.2, 1));
  width: var(--tk-mobile-drawer-width, 300px);
  max-width: min(var(--tk-mobile-drawer-width, 300px), var(--tk-mobile-drawer-max-width, calc(100vw - 36px)));
  min-width: min(var(--tk-mobile-drawer-width, 300px), var(--tk-mobile-drawer-max-width, calc(100vw - 36px)));
  box-sizing: border-box;
  padding: 18px;
  background: var(--tk-paper);
  border-right: 1px solid var(--tk-line);
  box-shadow: 18px 0 38px rgba(20, 20, 18, 0.16);
  transform: translateX(-104%);
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  gap: 16px;
  overflow: hidden;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  contain: layout paint;
}
.tk-mobile-drawer-head::after {
  content: "";
  position: absolute;
  left: -18px;
  right: -18px;
  bottom: -30px;
  height: 30px;
  background: linear-gradient(180deg, var(--tk-paper) 0%, color-mix(in srgb, var(--tk-paper) 86%, transparent) 46%, transparent 100%);
  pointer-events: none;
}
.tk-mobile-drawer-head {
  position: sticky;
  top: 0;
  z-index: 5;
  background: var(--tk-paper);
}
body.tk-mobile-menu-open .tk-mobile-drawer {
  transform: translateX(0);
}
.tk-mobile-drawer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.tk-mobile-drawer-head h2 {
  margin: 0;
  font-size: 20px;
  color: var(--tk-leaf-deep);
}
.tk-mobile-drawer-close {
  border: 0;
  background: var(--tk-leaf-soft);
  color: var(--tk-leaf-deep);
  width: 34px;
  height: 34px;
  border-radius: 999px;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
}
.tk-mobile-drawer-menu {
  display: grid;
  gap: 4px;
  align-content: start;
  grid-auto-rows: max-content;
  justify-items: stretch;
  min-height: 0;
  height: 100%;
  max-height: 100%;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-top: 2px;
  padding-bottom: 10px;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-y;
}
.tk-mobile-drawer-link {
  position: relative;
  overflow: hidden;
  border: 0;
  background: transparent;
  color: var(--tk-ink);
  text-align: left;
  text-decoration: none;
  padding: 12px 4px;
  border-bottom: 1px solid var(--tk-line);
  font: inherit;
  font-size: 16px;
  font-weight: 900;
  cursor: pointer;
}
.tk-mobile-drawer-link span,
.tk-mobile-drawer-link-icon {
  position: relative;
  z-index: 1;
}
.tk-mobile-drawer-link-icon {
  width: 36px;
  height: 36px;
  object-fit: contain;
}
.tk-mobile-drawer-link[data-menu-key="Digital"] {
  border-bottom-color: transparent;
}
.tk-mobile-drawer-link[data-mobile-last-item="true"] {
  border-bottom-color: transparent;
}
.tk-mobile-drawer-divider {
  display: block;
  width: 100%;
  height: 1px;
  margin: 6px 0;
  background: var(--tk-line);
  box-shadow: none;
  pointer-events: none;
}
.tk-mobile-drawer-link[data-menu-style="gameEntry"] {
  /* Founder Pass 10.6.x 2026-05-04 — founder rule (verbatim): "Light
     mode PLAY animations / smoke are not visible enough. Dark mode
     shows them. Light mode must show the same animated PLAY/smoke
     experience". Smoke opacity bumped from 0.2 → 0.42 (light) so
     the leaf-tinted radial-gradient layers read clearly against the
     cream paper background; dark mode overrides below set it back
     to 0.55 since dark backgrounds need more punch too. Pulse
     opacity bumped to keep the swipe band visible in light. */
  --tk-game-entry-smoke-opacity: 0.42;
  --tk-game-entry-smoke-duration: 6200ms;
  --tk-game-entry-pulse-opacity: 0.5;
  --tk-game-entry-pulse-duration: 3600ms;
  --tk-game-entry-scale: 1;
  --tk-game-entry-min-height: 48px;
  --tk-game-entry-padding-y: 10px;
  --tk-game-entry-divider-safe-gap: 6px;
  --tk-game-entry-smoke-inset: -36% -16%;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  min-height: var(--tk-game-entry-min-height);
  margin: var(--tk-game-entry-divider-safe-gap) 0;
  padding: var(--tk-game-entry-padding-y) 13px;
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 20%, transparent);
  border-radius: 18px;
  background:
    radial-gradient(circle at 16% 50%, color-mix(in srgb, var(--tk-leaf) 24%, transparent), transparent 38%),
    linear-gradient(135deg, var(--tk-leaf-deep), #173622);
  color: var(--tk-bg);
  box-shadow: 0 14px 34px color-mix(in srgb, var(--tk-leaf-deep) 22%, transparent);
  letter-spacing: 0.04em;
  overflow: hidden;
  isolation: isolate;
  transform: scale(var(--tk-game-entry-scale));
  transform-origin: center;
}
.tk-mobile-drawer-link[data-menu-style="gameEntry"] .tk-mobile-drawer-link-icon {
  display: block;
  width: 30px;
  height: 30px;
  flex: 0 0 30px;
  filter: drop-shadow(0 4px 9px rgba(0, 0, 0, 0.25));
}
.tk-mobile-drawer-link[data-menu-style="gameEntry"][data-pulse="true"]::before {
  content: "";
  position: absolute;
  inset: 0;
  /* Founder HARD CORRECTION 2026-05-03 — founder rule: "GREEN SMOKE
     EFFECTS, GREEN!!! MAKE IT THEME COLORS! ALSO MAKE SURE NETBICS
     WORKS TOO". Pulse + smoke now derive from --tk-leaf so the
     animation reads as brand-green on tiktoke and brand-blue on
     netbics, in BOTH themes. */
  background:
    linear-gradient(90deg, transparent 0%, color-mix(in srgb, var(--tk-leaf) 24%, transparent) 34%, color-mix(in srgb, var(--tk-leaf) 60%, transparent) 50%, transparent 70%);
  opacity: var(--tk-game-entry-pulse-opacity);
  transform: translateX(-120%);
  animation: tkGameEntryPulse var(--tk-game-entry-pulse-duration) ease-in-out infinite;
  z-index: 0;
  pointer-events: none;
}
.tk-mobile-drawer-link[data-menu-style="gameEntry"][data-smoke="true"]::after {
  content: "";
  position: absolute;
  inset: var(--tk-game-entry-smoke-inset);
  background:
    radial-gradient(ellipse at 24% 58%, color-mix(in srgb, var(--tk-leaf) 50%, transparent), transparent 30%),
    radial-gradient(ellipse at 56% 38%, color-mix(in srgb, var(--tk-leaf) 36%, transparent), transparent 34%),
    radial-gradient(ellipse at 76% 68%, color-mix(in srgb, var(--tk-warm) 24%, transparent), transparent 32%);
  opacity: var(--tk-game-entry-smoke-opacity);
  transform: translate3d(-6%, 8%, 0) scale(1);
  animation: tkGameEntrySmoke var(--tk-game-entry-smoke-duration) ease-in-out infinite;
  filter: blur(9px);
  pointer-events: none;
  z-index: 0;
}
.tk-mobile-drawer-link[data-menu-style="gameEntry"]:hover {
  color: var(--tk-paper);
  transform: translateY(-1px) scale(var(--tk-game-entry-scale));
}
@keyframes tkGameEntryPulse {
  0%, 18% { transform: translateX(-120%); opacity: 0; }
  42% { opacity: var(--tk-game-entry-pulse-opacity); }
  62%, 100% { transform: translateX(120%); opacity: 0; }
}
@keyframes tkGameEntrySmoke {
  0%, 100% { transform: translate3d(-8%, 9%, 0) scale(1); opacity: 0.08; }
  45% { transform: translate3d(8%, -5%, 0) scale(1.12); opacity: var(--tk-game-entry-smoke-opacity); }
  70% { transform: translate3d(3%, -10%, 0) scale(1.06); opacity: 0.16; }
}
@media (prefers-reduced-motion: reduce) {
  .tk-mobile-drawer-link[data-menu-style="gameEntry"][data-pulse="true"]::before,
  .tk-mobile-drawer-link[data-menu-style="gameEntry"][data-smoke="true"]::after {
    animation: none;
  }
}
.tk-mobile-drawer-link:hover {
  color: var(--tk-leaf-deep);
}
.tk-mobile-account {
  align-self: end;
  display: grid;
  gap: 10px;
  border-top: 1px solid var(--tk-line);
  padding-top: 14px;
}
.tk-mobile-account[hidden] {
  display: none;
}
.tk-mobile-account-greeting,
.tk-mobile-account-empty {
  margin: 0;
}
.tk-mobile-account-empty {
  color: var(--tk-muted);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: .1em;
  border-top: 1px solid var(--tk-line);
  padding-top: 14px;
}
.tk-mobile-account-greeting {
  display: grid;
  gap: 2px;
  color: var(--tk-ink-soft);
  font-size: 13px;
  letter-spacing: -0.01em;
}
.tk-mobile-account-greeting strong {
  color: var(--tk-leaf-deep);
  font-size: 19px;
  line-height: 1.05;
}
.tk-mobile-account-open {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 38px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 14%, transparent);
  background: rgba(216, 234, 216, 0.84);
  color: var(--tk-leaf-deep);
  font-size: 14px;
  font-weight: 850;
  text-decoration: none;
}

/* =============== MAIN =============== */
.tk-main {
  max-width: 1320px; margin: 0 auto;
  padding: 24px clamp(16px, 3vw, 28px) 96px;
  display: grid; gap: 28px;
}

body[data-tk-route-type="homepage"] .tk-main {
  /* Founder live edit 2026-04-29: the /demo homepage outer shell must be
     full-bleed during desktop freehand resize. The fixed Demo order state
     admin panel is viewport-positioned, so this wrapper cannot keep the old
     max-width/auto-margin shell that made the left edge stop early while
     full-bleed children reached the right side. Inner homepage sections own
     intentional padding below; do not reintroduce an outer boxed container. */
  width: 100%;
  max-width: none;
  margin-left: 0;
  margin-right: 0;
  display: block;
  padding-top: 0;
  padding-left: 0;
  padding-right: 0;
}

body.tk-account-route .tk-main {
  /* Founder live edit 2026-04-30: the route wrapper stays neutral and the
     config-owned inner account shell controls the half-width desktop layout.
     Do not restore the older full-bleed negative margin that left-aligned the
     account cards or made view-as role changes look like admin forms.
     padding-top:0 removes the extra 24px gap — body.tk-page already reserves
     fixed-header clearance on mobile; sticky desktop header needs none either. */
  width: 100%;
  max-width: none;
  margin-left: 0;
  margin-right: 0;
  display: block;
  padding-top: 0;
  padding-left: 0;
  padding-right: 0;
  transform: none !important;
}

/* Founder LIVE EDIT 2026-05-01 (MENU SYSTEM CORRECTION — single source,
   no per-page override): the prior `body.tk-account-route .tk-header-row
   { max-width: none; }` rule overrode the master 1320px max-width on
   the account page, making the header layout VISIBLY DIFFERENT from
   the homepage. Founder's exact rule: "REMOVE account-specific menu
   CSS / homepage-specific menu CSS / any conditional rendering that
   swaps menu layout. EVERY PAGE MUST POINT TO the same layout rules."
   The override is removed; account + homepage now render the IDENTICAL
   header from the single .tk-header-row rule with the canonical max-
   width clamp. Account-page section padding (.tk-account-page below)
   still respects the route-specific section padding token; only the
   header layout is unified. */

body.tk-account-route .tk-account-page {
  padding-left: var(--tk-account-section-pad, var(--tk-homepage-section-pad));
  padding-right: var(--tk-account-section-pad, var(--tk-homepage-section-pad));
}

body[data-tk-route-type="homepage"] .tk-main > :not([hidden]) + :not([hidden]),
body[data-tk-route-type="homepage"] .tk-homepage-rows:not([hidden]) {
  margin-top: 28px;
}

body[data-tk-route-type="homepage"] .tk-order-detail,
body[data-tk-route-type="homepage"] .tk-favorites-page,
body[data-tk-route-type="homepage"] .tk-product-page,
body[data-tk-route-type="homepage"] .tk-store-page,
body[data-tk-route-type="homepage"] .tk-account-page,
body[data-tk-route-type="homepage"] .tk-settings-page,
body[data-tk-route-type="homepage"] .tk-digital-page,
body[data-tk-route-type="homepage"] .tk-homepage-rows,
body[data-tk-route-type="homepage"] .tk-footer {
  padding-left: var(--tk-homepage-section-pad);
  padding-right: var(--tk-homepage-section-pad);
}

/* =============== ORDER + PLAY MERGED SECTION ===============
   Pass origin: Founder direct 2026-04-28 surgical UI pass + updated demo pass.
   The order section + play header carry NO border, NO outline, NO heavy
   background, NO shadow. The iframe is the game surface, and the wrapper fades
   into the page instead of reading as a boxed card. */
.tk-order {
  display: grid; gap: 18px;
  background: transparent;
  border: 0;
  padding: 4px 0 0;
}
.tk-order[hidden],
.tk-order-detail[hidden],
[data-tk-homepage-rows][hidden],
body.tk-order-blocked-route [data-tk-order],
body.tk-order-blocked-route [data-tk-order-detail] {
  display: none !important;
}
@keyframes tkPulse { 0%,100% { opacity: 1; } 50% { opacity: 0.55; } }

/* Founder LIVE EDIT BLOCK 2026-04-30 (inline desktop View Order
   placement): on desktop the View Order button must sit BELOW
   "Greenleaf Co · ON, Hamilton · ETA 22-28 min · order received",
   not floated to the right via flex space-between. flex-direction
   is column with align-items=flex-start so the order info reads as a
   stacked block and the View Order button (.tk-order-strip-aside)
   flows on the next row, left-aligned with the store name. The
   --tk-order-strip-direction var keeps this Founder-tunable; future
   admin work can switch back to row without re-editing CSS. Mobile
   path is unchanged because the .tk-order-strip { display: contents }
   override at the mobile media query takes precedence. */
.tk-order-strip {
  display: flex;
  flex-direction: var(--tk-order-strip-direction, column);
  align-items: var(--tk-order-strip-align, flex-start);
  justify-content: var(--tk-order-strip-justify, flex-start);
  gap: var(--tk-order-strip-gap, 12px);
  flex-wrap: wrap;
  order: var(--tk-order-desktop-strip-order, 1);
}
.tk-order-strip-main { display: grid; gap: 4px; min-width: 0; }
.tk-order-strip-aside {
  display: inline-flex; align-items: center; gap: 12px; flex-wrap: wrap;
}
.tk-order-kicker {
  margin: 0; font-size: 11px; letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--tk-warm); font-weight: 700;
}
.tk-order-store {
  margin: 0;
  font-size: clamp(25px, 3vw, 34px);
  line-height: 1.12;
  color: var(--tk-leaf-deep);
  font-weight: 900;
}
.tk-order-location {
  margin: 0;
  color: var(--tk-ink-soft);
  font-size: clamp(14px, 1.8vw, 17px);
  font-weight: 700;
  line-height: 1.18;
}
.tk-order-eta { margin: 0; color: var(--tk-muted); font-size: 14px; }
.tk-order-points {
  justify-self: center;
  text-align: center;
  padding: var(--tk-win-pill-padding, 6px 14px);
  border-radius: var(--tk-win-pill-radius, 14px);
  background: var(--tk-win-pill-bg, var(--tk-leaf-soft));
  border: var(--tk-win-pill-border, 0);
  display: inline-flex;
  align-items: baseline;
  justify-content: center;
  gap: var(--tk-win-pill-gap, 6px);
  line-height: 1.1;
  min-width: var(--tk-win-pill-min-width, auto);
  width: fit-content;
  margin-top: 4px;
  box-shadow: var(--tk-win-pill-shadow, none);
  transform-origin: center;
  animation: tkWinPillPulse var(--tk-win-pill-pulse-duration, 2.4s) ease-in-out infinite;
}
.tk-order-win-timer {
  /* Founder LIVE EDIT BLOCK 2026-04-30 (item 1 — restore BIG delivery
     countdown): under Be My Bud title we now stack a BIG MM:SS timer
     and a small AI's Accurate Estimation subtitle. The big number uses
     the same font weight/family as the delivered confirm timer
     (.tk-delivered-confirm-video small parity is approximate via
     leaf-deep + 950 weight). data-tk-bigStyle="true" turns on the big
     stack; the older 12px Title-case render is preserved for legacy
     usage when bigStyle=false. */
  margin: 4px 0 0;
  display: grid;
  gap: 2px;
  color: var(--tk-leaf);
  font-size: 12px;
  font-weight: 950;
  letter-spacing: 0.04em;
}
.tk-order-win-timer[data-tk-big-style="true"] {
  margin-top: 6px;
  gap: 0;
}
.tk-order-win-timer-big {
  font-size: clamp(28px, 4vw, 40px);
  font-weight: 900;
  color: var(--tk-leaf-deep);
  line-height: 1.05;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.tk-order-win-timer-subtitle {
  font-size: 11px;
  font-weight: 700;
  color: var(--tk-ink-soft);
  letter-spacing: 0.06em;
  text-transform: none;
}
.tk-order-win-timer-subtitle:empty {
  display: none;
}
.tk-order-points-label {
  font-size: var(--tk-win-pill-label-size, 11px);
  font-weight: 900;
  color: var(--tk-leaf-deep);
  letter-spacing: 0.12em;
}
.tk-order-points-value {
  font-size: var(--tk-win-pill-value-size, 13px);
  color: var(--tk-leaf-deep);
}

@keyframes tkWinPillPulse {
  0%, 100% {
    transform: scale(1);
    box-shadow: var(--tk-win-pill-pulse-shadow-start, var(--tk-win-pill-shadow, none));
  }
  50% {
    transform: scale(var(--tk-win-pill-pulse-scale, 1.035));
    box-shadow: var(--tk-win-pill-pulse-shadow-mid, var(--tk-win-pill-shadow, none));
  }
}

.tk-order-view {
  text-decoration: none;
  display: inline-flex; align-items: center; gap: 6px;
  /* Founder HARD CORRECTION 2026-05-03 — founder rule: "I CANT SEE
     VIEW ORDER TEXT ON MOBILE!!! U FIXED ON DESKTOP IT SHOULDNT
     HAVE BEEN DIFF ON MOBILE". Live probe (mobile viewport, light
     mode) showed color computed as rgb(31,61,44) — leaf-deep on
     leaf-deep, invisible. Some upstream rule is winning over the
     base color. !important locks the text to --tk-paper (cream)
     so it always reads against the dark-green pill in light mode.
     The dark-mode override below uses --tk-ink with !important. */
  background: var(--tk-leaf-deep) !important;
  color: var(--tk-paper) !important;
  padding: 9px 14px; border-radius: 999px;
  font-size: 13px; font-weight: 700;
  transition: transform .12s, background .15s;
}
.tk-order-view * {
  color: inherit !important;
}
.tk-order-view:hover { transform: translateY(-1px); background: var(--tk-leaf); color: var(--tk-paper); }
body[data-tk-route-type="homepage"] .tk-order-view {
  padding: var(--tk-view-order-homepage-padding, 12px 20px);
  font-size: var(--tk-view-order-homepage-font-size, 14px);
  transform: scale(var(--tk-view-order-homepage-scale, 1.16));
  transform-origin: center;
}
body[data-tk-route-type="homepage"] .tk-order-view:hover {
  transform: scale(var(--tk-view-order-homepage-scale, 1.16)) translateY(-1px);
}
body.tk-order-page .tk-order-view,
.tk-order-view[hidden] {
  display: none !important;
}
.tk-public-order-preview {
  position: absolute;
  z-index: var(--tk-public-order-preview-z-index, 18);
  left: 50%;
  bottom: calc(var(--tk-map-hero-article-overlap) + var(--tk-public-order-preview-desktop-offset, 34px));
  transform: translateX(-50%);
  border: 0;
  border-radius: 999px;
  padding: 14px 24px;
  background: var(--tk-leaf);
  color: #fff;
  font: inherit;
  font-weight: 950;
  letter-spacing: 0.02em;
  box-shadow: 0 18px 34px color-mix(in srgb, var(--tk-leaf) 26%, transparent);
  cursor: pointer;
}
/* Founder HARD CORRECTION 2026-05-03 — the "below-carousel" variant
   replaces the map-overlapping absolute position with natural flow
   below both the map AND the article carousel. Founder rule: "put
   the 'preview order' button right under the map+carousel. it
   interferes with the map too much". */
.tk-public-order-preview-below-carousel {
  position: static !important;
  display: block;
  margin: 18px auto 24px;
  transform: none !important;
  bottom: auto;
  left: auto;
}
.tk-public-order-preview-controls {
  /* Founder missed-items pass 2026-04-30 (item 9): Preview Order/Next step/End
     preview controls stay centered and use exactly 2/3 of the viewport width.
     Desktop max width caps at 460px so the buttons stay aesthetic on wide
     screens; mobile uses 66.66vw exactly. Width/margin come from
     business_map.publicPreview.style.controlsMaxWidth and
     controlsMobileMaxWidth so the rule stays JSON-owned. */
  display: grid;
  justify-items: center;
  width: var(--tk-public-order-preview-controls-max-width, min(66.66vw, 460px));
  max-width: var(--tk-public-order-preview-controls-max-width, min(66.66vw, 460px));
  gap: 6px;
  margin: var(--tk-public-order-preview-controls-margin-top, 10px) auto 0;
  order: var(--tk-public-order-preview-controls-order, 3);
}
@media (max-width: 720px) {
  .tk-public-order-preview-controls {
    width: var(--tk-public-order-preview-controls-mobile-max-width, 66.66vw);
    max-width: var(--tk-public-order-preview-controls-mobile-max-width, 66.66vw);
  }
}
.tk-public-order-preview-controls button {
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
  border: 0;
  border-radius: 999px;
  padding: 8px 12px;
  background: var(--tk-leaf);
  color: #fff;
  font: inherit;
  font-size: 12px;
  font-weight: 900;
  cursor: pointer;
}
.tk-public-order-preview-controls button + button {
  background: var(--tk-leaf-soft);
  color: var(--tk-leaf-deep);
}

.tk-order-progress {
  width: 100%;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0;
  order: var(--tk-order-desktop-progress-order, 3);
}
.tk-order-progress-step {
  flex: 1 1 0;
  min-width: 0;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  font-size: 10px; line-height: 1.1; color: var(--tk-muted); position: relative;
  text-align: center;
}
.tk-order-progress-step::after {
  content: ""; position: absolute; left: 50%; right: -50%; top: 6px; height: 2px;
  background: var(--tk-line); z-index: 0;
}
.tk-order-progress-step:last-child::after { display: none; }
.tk-order-progress-step[data-on="true"]::after { background: var(--tk-leaf); }
.tk-order-progress-step[data-on="active"]::after { background: linear-gradient(90deg, var(--tk-leaf) 50%, var(--tk-line) 50%); }
.tk-order-progress-dot {
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--tk-paper); border: 2px solid var(--tk-line); position: relative; z-index: 1;
}
.tk-order-progress-step[data-on="true"] .tk-order-progress-dot { background: var(--tk-leaf); border-color: var(--tk-leaf); }
.tk-order-progress-step[data-on="active"] .tk-order-progress-dot {
  background: var(--tk-warm); border-color: var(--tk-warm);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--tk-warm) 22%, transparent);
  animation: tkPulse 1.6s ease-in-out infinite;
}
.tk-order-progress-step[data-on="true"] .tk-order-progress-label,
.tk-order-progress-step[data-on="active"] .tk-order-progress-label { color: var(--tk-ink); font-weight: 600; }
.tk-order-progress-label {
  display: block;
  max-width: 100%;
  white-space: nowrap;
}

.tk-order-meta {
  display: flex; gap: 8px; flex-wrap: wrap; align-items: center; justify-content: center;
  order: var(--tk-order-desktop-meta-order, 4);
}
.tk-order-meta-pill {
  background: var(--tk-bg); border: 1px solid var(--tk-line); padding: 6px 12px; border-radius: 999px;
  font-size: 12px; color: var(--tk-ink-soft);
}
.tk-order-meta-pill strong { color: var(--tk-ink); }
.tk-order-meta-pill-soft { background: transparent; color: var(--tk-muted); border-style: dashed; }

.tk-order-map {
  position: relative;
  min-height: var(--tk-platform-map-active-order-height-desktop);
  overflow: hidden;
  border-radius: 0 0 22px 22px;
  background: #d8ead8;
  cursor: grab;
  order: var(--tk-order-desktop-map-order, 2);
  touch-action: none;
  overscroll-behavior: contain;
  user-select: none;
}
.tk-homepage-map-hero {
  /* Founder emergency order-map restore 2026-04-29: the full-width map is a
     separate homepage browsing hero, not the active-order map. It is hidden
     whenever a homepage active order is shown, so article/guide overlap never
     attaches to the order-status map.
     Founder LIVE EDIT 2026-04-30 (desktop right-edge overflow during resize —
     reported 5+ times): switched 100vw → var(--visual-vw, 100vw). CSS
     100vw includes the vertical scrollbar zone but document.body does not,
     so 100vw + margin-left:calc(50% - 50vw) produced a hero that extended
     ~15-17px past the right edge of the visible page on every desktop
     screen with a scrollbar. The visual delta was most obvious during
     freehand resize between full-width and iPad-ish breakpoints because
     the map's right edge no longer tracked the page's right edge as the
     viewport changed. --visual-vw is set in demo.js wireVisualViewport-
     HeightVariable from documentElement.clientWidth (which excludes the
     scrollbar) and updates on resize/visualViewport events, so the hero
     stays exactly flush to the viewport's content-edge at every width.
     Mobile has no persistent scrollbar so --visual-vw === innerWidth and
     this collapses to identical behavior — no mobile regression. */
  order: -20;
  /* Founder Pass 10.6.x 2026-05-04 — founder rule (verbatim): "I
     WANT TO SEE EVERY FUCKING OPTION LIVE AS I CHANGE IT. SO IF I
     MAKE IT IE. 90% SCRENWITH, OR FULL — I WANT TO SEE IT".
     Homepage map width was hardcoded `var(--visual-vw, 100vw)` so
     the admin `MAP WIDTH — DESKTOP/MOBILE` dropdowns never reached
     the rendered element. Now the var IS the width, with a sane
     full-bleed fallback if no admin choice is set. margin-inline:
     auto centers the box when the var is < 100vw. */
  width: var(--tk-platform-map-homepage-width-desktop, var(--visual-vw, 100vw));
  max-width: 100vw;
  height: var(--tk-platform-map-homepage-height-desktop);
  min-height: var(--tk-platform-map-homepage-height-desktop);
  margin-left: auto;
  margin-right: auto;
  border-radius: 0;
}
@media (max-width: 720px) {
  .tk-homepage-map-hero {
    width: var(--tk-platform-map-homepage-width-mobile, var(--visual-vw, 100vw));
    height: var(--tk-platform-map-homepage-height-mobile);
    min-height: var(--tk-platform-map-homepage-height-mobile);
  }
}
.tk-homepage-map-hero[hidden] {
  display: none !important;
}
.tk-active-order-map {
  /* Founder Pass 10.6.x 2026-05-04 — Active Order Map.
     INCIDENT HISTORY:
       v1: width: 100% (admin width var ignored entirely)
       v2: width: min(100%, var(...)) (admin var lost to parent width)
       v3: width: var(...); max-width: var(--tk-content-width)
           (clamped at 1180px → 5/6-screen / 90% / full-safe all
           rendered identical → "dropdown doesnt work")
       v4: width: var(...); max-width: 100vw (admin var wins, but
           if parent has padding the 100vw value forces parent
           horizontal-scroll → map extends past viewport edge)
       v5 (THIS): width: var(...); max-width: 100% (admin var wins
                 across full range, but max-width clamps to parent
                 available space so never extends past screen).
     Live verified on netbics.com /demo/order: width 100vw = 1264px
     inside the padded parent, x=88, rightEdge=1352, viewport=1440 —
     no overflow.

     STRICT RULES — DO NOT BREAK:
     - max-width MUST stay 100% (parent-fit). Anything larger
       (var(--tk-content-width), 100vw, etc.) reintroduces a known
       bug (v3 or v4 above).
     - width MUST stay var(...) with the dropdown's CSS var. Any
       wrapping `min(100%, var(...))` reintroduces v2 (admin var lost). */
  width: var(--tk-platform-map-active-order-width-desktop, 100%);
  max-width: 100%;
  min-height: var(--tk-platform-map-active-order-height-desktop);
  border-radius: 0 0 22px 22px;
  margin-left: auto;
  margin-right: auto;
}
@media (max-width: 720px) {
  .tk-active-order-map {
    width: var(--tk-platform-map-active-order-width-mobile, 100%);
    max-width: 100%;
    min-height: var(--tk-platform-map-active-order-height-mobile);
  }
}
.tk-order-map[data-dragging="true"] { cursor: grabbing; }
body.tk-map-interacting {
  overscroll-behavior: none;
  touch-action: none;
}
body.tk-order-page .tk-order-map {
  /* Founder Pass 10.6.x 2026-05-04 — View Order Map.
     INCIDENT HISTORY (founder reported overflow 50+ times):
       v1: width: 100% (admin var ignored)
       v2: width: min(100%, var(...)) (admin var lost to parent)
       v3: width: var(...); NO max-width (admin var wins but
           `full-safe` = 100vw overflowed by ~88px → right edge
           past viewport)
       v4: width: var(...); max-width: 100vw (still overflowed
           because the padded parent forced horizontal-scroll
           when the var hit 100vw — Playwright proved x=88,
           rightEdge=1528 on a 1440 viewport)
       v5 (THIS): width: var(...); max-width: 100% (clamps to
                 parent's available content space — never overflows
                 the screen, admin var wins across the 66-100vw
                 range up to parent width).

     STRICT RULES — DO NOT BREAK:
     - max-width MUST stay 100% (parent-fit). 100vw / 100% /
       content-width all sound similar but are NOT — only 100%
       prevents the parent-overflow path (v4).
     - width MUST stay var(...) with the dropdown's CSS var.
     - The map is a DIRECT child of the order template; if you
       move it inside another padded wrapper, re-test the
       overflow case on /demo/order with width=full-safe at 1440. */
  width: var(--tk-platform-map-order-width-desktop, 100%);
  max-width: 100%;
  margin-left: auto;
  margin-right: auto;
  min-height: var(--tk-platform-map-order-height-desktop);
}
@media (max-width: 720px) {
  body.tk-order-page .tk-order-map {
    width: var(--tk-platform-map-order-width-mobile, 100%);
    max-width: 100%;
    min-height: var(--tk-platform-map-order-height-mobile);
  }
}
.tk-order-map::before {
  content: "";
  position: absolute;
  z-index: 4;
  inset: 0 0 auto;
  height: var(--tk-platform-map-top-fade-height);
  pointer-events: none;
  background: linear-gradient(to bottom, var(--tk-bg), transparent);
}
.tk-order-map::after {
  content: "";
  position: absolute;
  z-index: 4;
  inset: auto 0 0;
  height: clamp(72px, 10vw, 140px);
  pointer-events: none;
  /* Founder HARD CORRECTION 2026-05-04 — founder rule (verbatim):
     "YOU TOOK OFF THE FADING OFF MY MAPS on mobile! PUT IT BACK TO
     WHATEVER IT WAS!" Background token swap from var(--tk-paper) to #e3e2e0
     left the start-color of this gradient as the OLD cream
     (color-mix(in srgb, var(--tk-paper) 0%, transparent)) — the fade still existed mathematically but
     read as washed-out / invisible because the transparent-cream
     start color no longer matched the new grey bg endpoint, so the
     mid-transition rendered as muddy and the fade didn't visually
     dissolve into the page. Pin start-color to var(--tk-bg) at alpha
     0 via color-mix so it ALWAYS matches the live bg, no matter
     which token swap happens next. */
  background: linear-gradient(to bottom, color-mix(in srgb, var(--tk-bg) 0%, transparent), var(--tk-bg));
}

body[data-tk-route-type="homepage"][data-tk-homepage-map-mode="activeOrderCompact"] .tk-order {
  width: 100%;
  max-width: 100%;
  min-width: 0;
  justify-self: stretch;
  margin-left: 0;
  margin-right: 0;
  gap: 18px;
  padding-top: 4px;
  padding-left: 0;
  padding-right: 0;
}
body[data-tk-route-type="homepage"][data-tk-homepage-map-mode="activeOrderCompact"] .tk-order-strip,
body[data-tk-route-type="homepage"][data-tk-homepage-map-mode="activeOrderCompact"] .tk-order-progress,
body[data-tk-route-type="homepage"][data-tk-homepage-map-mode="activeOrderCompact"] .tk-order-meta,
body[data-tk-route-type="homepage"][data-tk-homepage-map-mode="activeOrderCompact"] .tk-play-head {
  width: calc(100% - (2 * var(--tk-homepage-section-pad)));
  justify-self: center;
  margin-left: 0;
  margin-right: 0;
}
body[data-tk-route-type="homepage"][data-tk-homepage-map-mode="activeOrderCompact"] .tk-active-order-map,
body[data-tk-route-type="homepage"][data-tk-homepage-map-mode="activeOrderCompact"] .tk-play-frame {
  width: calc(100% - (2 * var(--tk-homepage-section-pad)));
  justify-self: center;
  margin-left: 0;
  margin-right: 0;
  max-width: none;
}
body[data-tk-route-type="homepage"][data-tk-homepage-map-mode="activeOrderCompact"] .tk-active-order-map {
  order: var(--tk-order-desktop-map-order, 2);
  max-width: var(--tk-platform-map-active-order-max-width);
  min-height: var(--tk-platform-map-active-order-height-desktop);
  border-radius: 0 0 22px 22px;
}
.tk-delivered-confirmation {
  order: var(--tk-order-desktop-map-order, 2);
  width: calc(100% - (2 * var(--tk-homepage-section-pad)));
  max-width: var(--tk-platform-map-active-order-max-width);
  justify-self: center;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  justify-items: center;
  text-align: center;
  gap: 18px;
  padding: clamp(18px, 3vw, 32px);
  border-radius: 0 0 22px 22px;
  border: 0;
  background:
    radial-gradient(circle at 50% 0%, color-mix(in srgb, var(--tk-leaf) 14%, transparent), transparent 40%),
    transparent;
  box-shadow: none;
}
.tk-delivered-confirmation-head,
.tk-delivered-confirmation-actions,
.tk-delivered-guidance {
  display: grid;
  gap: 10px;
  align-content: center;
  justify-items: center;
  max-width: 620px;
}
.tk-delivered-confirmation-head h3 {
  margin: 0;
  color: var(--tk-leaf-deep);
  font-size: clamp(22px, 3vw, 34px);
  letter-spacing: -0.04em;
}
.tk-delivered-confirmation-head p,
.tk-delivered-guidance li,
.tk-delivered-photo-status {
  margin: 0;
  color: var(--tk-ink-soft);
}
.tk-delivered-reward-cue,
.tk-delivered-timer-lead {
  color: var(--tk-warm);
  font-weight: 1000;
  letter-spacing: 0.01em;
}
.tk-delivered-reward-arrow {
  --tk-delivered-reward-arrow-color: var(--tk-leaf-light);
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  max-width: min(100%, 620px);
  margin-bottom: var(--tk-delivered-arrow-clearance-desktop, 110px);
  color: var(--tk-delivered-reward-arrow-color);
  font-weight: 1000;
  letter-spacing: 0.03em;
  text-wrap: balance;
  text-shadow: 0 8px 22px color-mix(in srgb, var(--tk-leaf-light) 28%, transparent);
}
.tk-delivered-confirmation[data-tk-delivered-skipped="true"] .tk-delivered-reward-arrow {
  display: none;
}
.tk-delivered-cta-arrow {
  position: absolute;
  right: var(--tk-delivered-arrow-desktop-right, -24px);
  top: var(--tk-delivered-arrow-desktop-top, calc(100% - 1px));
  z-index: 2;
  width: var(--tk-delivered-arrow-desktop-width, 230px);
  height: var(--tk-delivered-arrow-desktop-height, 310px);
  color: var(--tk-delivered-reward-arrow-color);
  opacity: var(--tk-delivered-arrow-opacity, 0.96);
  transform: rotate(var(--tk-delivered-arrow-rotation, 0deg));
  pointer-events: none;
  filter: drop-shadow(0 12px 16px rgba(38, 130, 58, 0.18));
}
.tk-delivered-cta-arrow svg {
  width: 100%;
  height: 100%;
  overflow: visible;
}
.tk-delivered-cta-arrow-under,
.tk-delivered-cta-arrow-main,
.tk-delivered-cta-arrow-head {
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.tk-delivered-cta-arrow-under {
  opacity: 0.22;
  stroke-width: calc(var(--tk-delivered-arrow-stroke-width, 8) * 1.85);
}
.tk-delivered-cta-arrow-main,
.tk-delivered-cta-arrow-head {
  stroke-width: var(--tk-delivered-arrow-stroke-width, 8);
}
.tk-delivered-reward-dollar {
  display: inline-grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--tk-leaf-light) 22%, transparent);
}
.tk-delivered-confirmation-actions {
  position: relative;
  width: min(100%, 380px);
}
.tk-delivered-confirmation-actions[hidden] {
  display: none;
}
.tk-delivered-confirm-photo,
.tk-delivered-not-now,
.tk-delivered-confirm-video {
  width: min(100%, 360px);
  min-height: 48px;
  border: 0;
  border-radius: 999px;
  font: inherit;
  font-weight: 950;
  letter-spacing: 0.02em;
  cursor: pointer;
  align-items: center;
  justify-content: center;
  gap: 8px;
  white-space: nowrap;
}
.tk-delivered-confirm-photo {
  display: inline-flex;
  min-height: 62px;
  background: var(--tk-leaf);
  color: #fff;
  box-shadow: 0 14px 26px color-mix(in srgb, var(--tk-leaf) 24%, transparent);
}
.tk-delivered-not-now {
  display: inline-flex;
  min-height: 38px;
  background: var(--tk-leaf-deep);
  color: var(--tk-paper);
}
.tk-delivered-confirm-video {
  display: inline-flex;
  flex-wrap: wrap;
  column-gap: var(--tk-delivered-video-gap, 4px);
  row-gap: var(--tk-delivered-video-coming-soon-gap, 2px);
  background: rgba(127, 130, 117, 0.26);
  color: color-mix(in srgb, var(--tk-leaf-deep) 58%, transparent);
  cursor: not-allowed;
}
.tk-delivered-confirm-video small {
  display: block;
  width: 100%;
  font-size: 10px;
  line-height: 0.95;
  font-weight: 850;
  margin-top: var(--tk-delivered-video-coming-soon-gap, 2px);
}
.tk-delivered-button-icon {
  width: 22px;
  height: 22px;
  flex: 0 0 auto;
}
.tk-delivered-confirmation-actions[data-skip-state="animating"] {
  min-height: 138px;
  place-items: center;
}
.tk-delivered-check-effect {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: 128px;
  height: 128px;
  color: var(--tk-delivered-check-color, var(--tk-leaf));
  isolation: isolate;
}
.tk-delivered-check-effect::before {
  content: "";
  position: absolute;
  inset: 8px;
  border-radius: 999px;
  border: 4px solid currentColor;
  opacity: 0;
  box-shadow: 0 0 34px var(--tk-delivered-check-glow, color-mix(in srgb, var(--tk-leaf-light) 38%, transparent));
  animation: tkDeliveredCheckRing var(--tk-delivered-check-duration, 940ms) ease-out forwards;
}
.tk-delivered-check-svg {
  position: relative;
  z-index: 1;
  width: 118px;
  height: 118px;
  filter: drop-shadow(0 18px 24px var(--tk-delivered-check-glow, color-mix(in srgb, var(--tk-leaf-light) 38%, transparent)));
  animation: tkDeliveredCheckPop var(--tk-delivered-check-duration, 940ms) cubic-bezier(.2, 1.42, .28, 1) forwards;
}
@keyframes tkDeliveredCheckPop {
  0% {
    opacity: 0;
    transform: scale(0.52) rotate(-8deg);
  }
  34% {
    opacity: 1;
    transform: scale(1.16) rotate(0deg);
  }
  74% {
    opacity: 1;
    transform: scale(1) rotate(0deg);
  }
  100% {
    opacity: 0;
    transform: scale(0.72) rotate(0deg);
  }
}
@keyframes tkDeliveredCheckRing {
  0% {
    opacity: 0.52;
    transform: scale(0.64);
  }
  70% {
    opacity: 0.18;
    transform: scale(1.32);
  }
  100% {
    opacity: 0;
    transform: scale(1.52);
  }
}
.tk-delivered-phone-required {
  margin: 0;
  color: #b3261e;
  font-weight: 900;
}

.tk-spin-wheel-open .tk-shell,
.tk-spin-wheel-open .tk-header,
.tk-spin-wheel-open .tk-route-shell {
  filter: blur(var(--tk-spin-wheel-blur, 10px));
}
.tk-spin-wheel-overlay {
  /* Founder LIVE EDIT BLOCK 2026-04-30 (item 1 — mobile centering):
     symmetric viewport-anchored centering. The previous rule used
     padding: clamp(...) which on mobile with safe-area insets could
     produce uneven left/right margins (right edge clipped). We pin
     padding equally on all four sides plus env(safe-area-inset-*) so
     the card sits dead-center in the visible viewport on every device,
     including notched displays. */
  /* Founder LIVE EDIT 2026-05-01 (FIRST VISIT STACK ORDER FIX —
     SPIN WHEEL POPUP LAYER): bumped z-index from 140 to 8500 to
     match Founder's "Other popups (spin wheel): 8500" hierarchy
     entry. Sits ABOVE the privacy banner (5000) and header (4000)
     but BELOW the age check (9000) and location picker (9999) so
     a popup can never visually cover an active age/location modal
     that the user must satisfy first. */
  position: fixed;
  inset: 0;
  z-index: 8500;
  display: grid;
  place-items: center;
  padding-top: max(clamp(16px, 5vw, 36px), env(safe-area-inset-top, 0px));
  padding-right: max(clamp(16px, 5vw, 36px), env(safe-area-inset-right, 0px));
  padding-bottom: max(clamp(16px, 5vw, 36px), env(safe-area-inset-bottom, 0px));
  padding-left: max(clamp(16px, 5vw, 36px), env(safe-area-inset-left, 0px));
  background: var(--tk-spin-wheel-overlay-bg, rgba(13, 22, 16, 0.38));
  backdrop-filter: blur(var(--tk-spin-wheel-blur, 10px));
}
.tk-spin-wheel-card {
  /* Founder LIVE EDIT BLOCK 2026-04-30 (mobile right-side clipping fix):
     the card width is bounded by the available content area (100%) so
     it can NEVER exceed the overlay's safe-area padding box. The
     previous min(94vw, 540px) used vw which is the LARGE viewport
     width on iOS Safari (excludes browser chrome from the math), so
     when the address bar collapsed the 94vw briefly exceeded 100%
     and clipped the right edge. Switching to min(100%, 540px) makes
     the card respect the parent's actual available width which is
     already padded symmetrically by env(safe-area-inset-*) on the
     overlay. justify-self: center forces dead-center alignment in
     the grid place-items: center context. */
  position: relative;
  width: min(100%, 540px);
  max-width: min(100%, 540px);
  justify-self: center;
  margin-inline: auto;
  display: grid;
  justify-items: center;
  gap: 16px;
  padding: clamp(18px, 4vw, 32px);
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: 30px;
  background: var(--tk-spin-wheel-card-bg, radial-gradient(circle at 50% 0%, color-mix(in srgb, var(--tk-leaf-light) 20%, transparent), transparent 44%), color-mix(in srgb, var(--tk-paper) 94%, transparent));
  opacity: var(--tk-spin-wheel-card-opacity, 0.96);
  box-shadow: 0 34px 90px rgba(0, 0, 0, 0.28);
  text-align: center;
  transform: scale(var(--tk-spin-wheel-card-scale, 1));
  transform-origin: center;
}
.tk-spin-wheel-overlay[data-disable-white-panel="true"] .tk-spin-wheel-card {
  background: radial-gradient(circle at 50% 0%, color-mix(in srgb, var(--tk-leaf-light) 24%, transparent), transparent 52%), color-mix(in srgb, var(--tk-leaf-deep) 34%, transparent);
  border-color: color-mix(in srgb, var(--tk-paper) 18%, transparent);
  backdrop-filter: blur(var(--tk-spin-wheel-blur, 10px));
}
/* Founder LIVE EDIT BLOCK 2026-04-30 (true remove modal background
   entirely): when removeModalBackgroundEntirely is ON, the card has
   no fill, no border, no shadow, no backdrop-filter. Wheel/pointer/
   close X/STOP-CLAIM remain visible because they have their own
   styling. The page backdrop blur from the overlay still applies
   unless Founder separately disables it. This rule has higher
   specificity than the disable-white-panel and cardOpacity rules
   so it overrides both. */
.tk-spin-wheel-overlay[data-remove-modal-background="true"] .tk-spin-wheel-card,
.tk-spin-wheel-overlay[data-remove-modal-background="true"][data-disable-white-panel="true"] .tk-spin-wheel-card {
  background: transparent !important;
  border: 0 !important;
  box-shadow: none !important;
  backdrop-filter: none !important;
  opacity: 1 !important;
}
.tk-spin-wheel-card header {
  display: grid;
  gap: 5px;
  max-width: 36rem;
}
.tk-spin-wheel-card h2,
.tk-spin-wheel-card p,
.tk-spin-wheel-card small {
  margin: 0;
}
.tk-spin-wheel-card h2 {
  /* Founder LIVE EDIT 2026-05-01 (Spin To Win headline color):
     "MAKE the 'Spin To Win!' text the Main theme Green, instead of
     dark green." Switched from --tk-leaf-deep (var(--tk-leaf-deep, #1f3d2c), the dark
     green) to --tk-leaf (var(--tk-leaf, #3a8f5a), the main brand green). The
     popup card background already has a soft green halo so the
     brighter --tk-leaf reads as a confident headline against it. */
  color: var(--tk-leaf, var(--tk-leaf, #3a8f5a));
  font-size: clamp(25px, 5vw, 42px);
  line-height: 0.95;
}
.tk-spin-wheel-card header > p:last-child,
.tk-spin-wheel-card header small {
  color: var(--tk-ink-soft);
  font-weight: 800;
}
.tk-spin-wheel-close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 34px;
  height: 34px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid var(--tk-spin-wheel-close-border);
  border-radius: 999px;
  background: var(--tk-spin-wheel-close-bg);
  color: var(--tk-spin-wheel-close-color);
  line-height: 1;
  cursor: pointer;
  transition: background-color .16s ease, color .16s ease, box-shadow .16s ease, transform .16s ease;
}
.tk-spin-wheel-close:hover,
.tk-spin-wheel-close:focus-visible {
  background: var(--tk-spin-wheel-close-hover-bg);
  color: var(--tk-spin-wheel-close-hover-color);
  box-shadow: var(--tk-spin-wheel-close-focus-shadow);
}
.tk-spin-wheel-close:focus-visible {
  outline: 0;
}
.tk-spin-wheel-close:active {
  transform: scale(0.96);
}
.tk-spin-wheel-close-icon {
  width: 17px;
  height: 17px;
  display: block;
}
.tk-spin-wheel-stage {
  position: relative;
  width: var(--tk-spin-wheel-size, min(72vw, 320px));
  aspect-ratio: 1;
  display: grid;
  place-items: center;
}
.tk-spin-wheel-pointer {
  position: absolute;
  top: -10px;
  z-index: 3;
  width: 0;
  height: 0;
  border-left: 16px solid transparent;
  border-right: 16px solid transparent;
  border-top: 30px solid var(--tk-spin-wheel-pointer-color, var(--tk-warm));
  filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.24));
}
.tk-spin-wheel-disc {
  width: 100%;
  height: 100%;
  border-radius: 999px;
  border: 8px solid var(--tk-spin-wheel-border-color, var(--tk-paper));
  position: relative;
  overflow: hidden;
  transition: transform var(--tk-spin-wheel-duration, 4200ms) cubic-bezier(.14,.8,.12,1);
  box-shadow: inset 0 0 0 2px color-mix(in srgb, var(--tk-leaf-deep) 16%, transparent), 0 22px 44px color-mix(in srgb, var(--tk-leaf-deep) 24%, transparent);
}
.tk-spin-wheel-disc[data-spinning="true"] {
  animation: tkVaultSpinLinear 760ms linear infinite;
}
.tk-spin-wheel-disc[data-spinning="false"] {
  animation: none;
}
.tk-spin-wheel-disc::after {
  content: "";
  position: absolute;
  inset: 37%;
  border-radius: 999px;
  background: var(--tk-paper);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--tk-leaf-deep) 12%, transparent);
}
.tk-spin-wheel-label {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 34%;
  min-width: 56px;
  transform:
    translate(-50%, -50%)
    rotate(var(--tk-spin-label-angle))
    translateY(calc(-1 * var(--tk-spin-wheel-label-radius, 38%)))
    rotate(var(--tk-spin-label-angle-inverse));
  transform-origin: center;
  color: var(--tk-spin-label-color, #fff);
  font-size: var(--tk-spin-wheel-label-font-size, 11px);
  font-weight: 1000;
  line-height: 1.1;
  text-align: center;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.42);
  z-index: 1;
  pointer-events: none;
}
.tk-spin-wheel-button,
.tk-spin-admin-actions button {
  border: 0;
  border-radius: 999px;
  background: var(--tk-leaf);
  color: #fff;
  font-weight: 1000;
  min-height: 44px;
  padding: 0 22px;
  cursor: pointer;
}
.tk-spin-wheel-button {
  transform: scale(var(--tk-spin-wheel-button-scale, 1));
  transform-origin: center;
}
.tk-spin-wheel-result {
  min-height: 22px;
  margin: 0;
  color: var(--tk-leaf-deep);
  font-weight: 1000;
}
@keyframes tkVaultSpinLinear {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}
@media (max-width: 680px) {
  .tk-spin-wheel-stage {
    width: var(--tk-spin-wheel-mobile-size, min(82vw, 310px));
  }
  .tk-spin-admin-field {
    grid-template-columns: 1fr;
    gap: 7px;
  }
}
.tk-spin-admin {
  display: grid;
  gap: 16px;
}
/* Founder PASS 53 2026-05-01 (spin wheel campaign ON/OFF visibility):
   the visibility toggle next to public copy fields used to render a
   single static "OFF" label, so the founder couldn't tell whether the
   field was currently ON or OFF. Now the markup carries both ON and OFF
   spans; CSS hides the inactive one based on :has(input:checked) and
   colors the pill green for ON / red for OFF so the state reads at a
   glance on desktop and mobile. */
.tk-spin-copy-off-toggle {
  display: inline-flex;
  align-items: center;
  gap: 0;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11px;
  font-weight: 950;
  letter-spacing: 0.04em;
  cursor: pointer;
  user-select: none;
  background: color-mix(in srgb, var(--tk-leaf) 18%, transparent);
  color: var(--tk-leaf-deep);
  border: 1px solid color-mix(in srgb, var(--tk-leaf) 42%, transparent);
  transition: background-color .14s ease, color .14s ease, border-color .14s ease;
}
.tk-spin-copy-off-toggle input { display: none; }
.tk-spin-copy-off-toggle .tk-spin-copy-state-on  { display: inline; }
.tk-spin-copy-off-toggle .tk-spin-copy-state-off { display: none; }
.tk-spin-copy-off-toggle:has(input:checked) {
  background: rgba(214, 65, 65, 0.18);
  color: #b32424;
  border-color: rgba(214, 65, 65, 0.5);
}
.tk-spin-copy-off-toggle:has(input:checked) .tk-spin-copy-state-on  { display: none; }
.tk-spin-copy-off-toggle:has(input:checked) .tk-spin-copy-state-off { display: inline; }
.tk-spin-copy-control {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.tk-spin-admin > h3,
.tk-spin-admin > p {
  margin: 0;
}
.tk-spin-admin-group {
  display: grid;
  gap: 14px;
  padding: clamp(14px, 2vw, 20px);
  border: 1px solid color-mix(in srgb, var(--tk-line) 86%, transparent);
  border-radius: 22px;
  background: color-mix(in srgb, var(--tk-paper) 88%, var(--tk-leaf-soft));
  box-shadow: 0 16px 36px rgba(20, 20, 18, 0.07);
}
.tk-spin-admin-group summary {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  cursor: pointer;
  list-style: none;
}
.tk-spin-admin-group summary::-webkit-details-marker { display: none; }
.tk-spin-admin-group summary::after {
  content: "";
  width: 9px;
  height: 9px;
  border-right: 2px solid var(--tk-leaf-deep);
  border-bottom: 2px solid var(--tk-leaf-deep);
  transform: rotate(45deg);
  transition: transform .18s ease;
}
.tk-spin-admin-group[open] summary::after {
  transform: rotate(225deg);
}
.tk-spin-admin-group summary div {
  display: grid;
  gap: 4px;
}
.tk-spin-admin-group h4,
.tk-spin-admin-group p {
  margin: 0;
}
.tk-spin-admin-group h4 {
  color: var(--tk-leaf-deep);
}
.tk-spin-admin-group p,
.tk-spin-admin-field small {
  color: var(--tk-muted);
}
.tk-spin-admin-grid {
  display: grid;
  gap: 12px;
}
.tk-spin-admin-field {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(130px, 240px);
  gap: 16px;
  align-items: center;
}
.tk-spin-admin-field > span {
  display: grid;
  gap: 3px;
}
.tk-spin-admin-field input,
.tk-spin-admin-field select,
.tk-spin-admin-field textarea {
  width: 100%;
  min-height: 38px;
  border: 1px solid var(--tk-line);
  border-radius: 14px;
  background: var(--tk-paper);
  color: var(--tk-ink);
  padding: 8px 10px;
  font: inherit;
}
.tk-spin-copy-control {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 8px;
}
.tk-spin-copy-control input {
  min-width: 0;
}
.tk-spin-copy-off-toggle {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  min-height: 34px;
  padding: 6px 8px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--tk-leaf-soft) 78%, transparent);
  color: var(--tk-leaf-deep);
  font-size: 11px;
  font-weight: 950;
}
.tk-notification-tokebucks-ledger p {
  display: grid;
  gap: 2px;
}
.tk-notification-tokebucks-ledger h3,
.tk-notification-friends h3,
.tk-notification-referrals h3,
.tk-friends-online-button {
  /* Founder LIVE EDIT BLOCK 2026-04-30 (item 6 — Activity menu colors):
     "Activity", "Friends", and "Referrals" headings in the activity
     popover use theme dark green (--tk-leaf-deep), not regular green or
     a hardcoded color. The token is the canonical platform dark green;
     no #hex value should appear here. */
  color: var(--tk-leaf-deep);
}
.tk-notifications-popover h2 {
  /* Founder LIVE EDIT BLOCK 2026-04-30 (item 6): "Activity" panel title
     also uses theme dark green to keep all three headings consistent. */
  color: var(--tk-leaf-deep);
}
/* Founder LIVE EDIT BLOCK 2026-04-30 (item 7 — Account Logout button):
   the account header puts the headline copy on the left and the Logout
   button on the right; on mobile they stack with the button right-
   aligned. Theme tokens only — no hardcoded colors. The button uses
   the existing data-tk-logout hook so the existing logout handler
   fires unchanged. */
.tk-account-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
}
.tk-account-head-copy { flex: 1 1 auto; min-width: 0; }
.tk-account-logout {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border-radius: 999px;
  border: 1px solid var(--tk-line);
  background: var(--tk-paper);
  color: var(--tk-leaf-deep);
  font-weight: 800;
  font-size: 13px;
  cursor: pointer;
}
.tk-account-logout:hover {
  background: color-mix(in srgb, var(--tk-leaf-soft) 60%, transparent);
}
.tk-account-logout .tk-icon { width: 16px; height: 16px; }
@media (max-width: 720px) {
  .tk-account-head { flex-wrap: wrap; }
  .tk-account-logout { align-self: flex-end; }
}
.tk-notification-tokebucks-ledger strong {
  color: var(--tk-leaf);
  font-size: 15px;
}
.tk-spin-admin-section-card {
  display: grid;
  gap: 10px;
  padding: 12px;
  border: 1px solid var(--tk-line);
  border-radius: 18px;
  background: color-mix(in srgb, var(--tk-paper) 92%, transparent);
}
.tk-spin-admin-section-card header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
}
.tk-spin-admin-section-card header label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--tk-muted);
  font-size: 12px;
  font-weight: 900;
}
.tk-spin-admin-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.tk-spin-admin-search-results {
  display: grid;
  gap: 8px;
}
.tk-spin-admin-search-results button {
  border: 1px solid var(--tk-line);
  border-radius: 14px;
  background: var(--tk-paper);
  color: var(--tk-ink);
  padding: 9px 10px;
  display: flex;
  justify-content: space-between;
  gap: 10px;
  text-align: left;
  cursor: pointer;
}
.tk-spin-admin pre {
  max-height: 220px;
  overflow: auto;
  margin: 0;
  padding: 10px;
  border-radius: 12px;
  background: color-mix(in srgb, var(--tk-leaf-deep) 8%, transparent);
  color: var(--tk-ink-soft);
  white-space: pre-wrap;
}
body[data-tk-animations="off"] .tk-spin-wheel-disc {
  transition-duration: 1ms !important;
  animation: none !important;
}
.tk-delivered-flash-instruction {
  width: min(100%, 360px);
  margin: 0;
  color: var(--tk-warm);
  font-weight: 950;
  text-align: center;
}
.tk-delivered-flash-instruction[hidden] {
  display: none !important;
}
.tk-delivered-timer {
  position: relative;
  z-index: 3;
  color: var(--tk-leaf-deep);
  font-weight: 950;
  font-size: clamp(24px, 4vw, 42px);
  letter-spacing: -0.04em;
}
.tk-delivered-guidance {
  text-align: left;
}
.tk-delivered-guidance ul {
  margin: 0;
  padding-left: 18px;
}
.tk-delivered-guidance {
  padding: 14px;
  border-radius: 16px;
  background: color-mix(in srgb, var(--tk-leaf-deep) 8%, transparent);
}
.tk-delivered-guidance strong {
  color: var(--tk-leaf-deep);
}
.tk-delivered-guidance ul {
  margin: 0;
  padding-left: 18px;
}
/* Founder live map pass 2026-04-29: zoom-out must never reveal a centered
   square/rectangle inside the homepage hero. The custom OSM canvas is larger
   than the clipped map shell, so scaling down still leaves tile coverage while
   JS repositions cached tiles from config/site/homepage.json business_map.map. */
[data-tk-platform-map] {
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  overscroll-behavior: contain;
}
.tk-platform-map-canvas {
  position: absolute;
  inset: calc(-1 * var(--tk-platform-map-zoom-overscan));
  transform: scale(var(--tk-platform-map-zoom));
  transform-origin: center;
  transition: transform .16s ease-out;
  background: #d8ead8;
  touch-action: none;
  will-change: transform;
  backface-visibility: hidden;
  contain: layout paint;
  -webkit-user-select: none;
  user-select: none;
}
body.tk-map-interacting .tk-platform-map-canvas {
  transition: none;
}
.tk-platform-map-tiles {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: #d8ead8;
}
.tk-platform-map-tiles img {
  position: absolute;
  width: 256px;
  height: 256px;
  max-width: none;
  user-select: none;
  pointer-events: none;
  display: block;
  will-change: left, top;
  image-rendering: auto;
}
/* Founder HARD CORRECTION 2026-05-03 — dark-mode map for OSM/raster
   tiles. Google Maps has its own dark Map ID / styles array path
   (run.js mountGoogleMapsForRoot ~line 7458) so we restrict this
   filter to the OSM/raster case via :not([data-tk-google-maps-active]).
   The filter inverts luminance and rotates hue 180° so green stays
   green while paper-white becomes near-black — the standard recipe
   for adapting any light raster tileset to dark mode without
   downloading a separate dark tile pack. */
:root[data-theme="dark"] .tk-platform-map-tiles:not([data-tk-google-maps-active]) {
  background: var(--tk-bg);
}
:root[data-theme="dark"] .tk-platform-map-tiles:not([data-tk-google-maps-active]) img {
  filter: invert(1) hue-rotate(180deg) brightness(0.92) saturate(0.85);
}

/* Founder HARD CORRECTION 2026-05-03 — Sign Up + Log In buttons
   collapse to icons only. Founder rule: "switch the LOGIN and
   SIGNUP text to just icons". The labels stay in DOM for screen
   readers via .tk-visually-hidden, the visible button is just the
   24×24 SVG matching the other header icons (cart, heart, etc.). */
.tk-visually-hidden {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

/* Founder HARD CORRECTION 2026-05-03 — dark-mode overrides for
   surfaces that were hardcoded to white/cream and ignored the
   theme token map. Founder reports: product cards stayed white,
   the map's bottom fade stayed cream, the header bottom fade
   "still goes to white" in dark mode. Each rule below points the
   hardcoded gradient/fill at var(--tk-bg) / var(--tk-paper) so it
   tracks the theme token. The base light-mode rules stay
   untouched; this block ONLY runs under :root[data-theme="dark"]. */
:root[data-theme="dark"] .tk-product-3d-stage,
:root[data-theme="dark"] .tk-product-3d-fallback-image {
  background: linear-gradient(180deg, var(--tk-paper) 0%, var(--tk-paper-strong) 100%);
}
:root[data-theme="dark"] .tk-tokebot {
  background: linear-gradient(140deg, var(--tk-paper) 0%, var(--tk-paper-strong) 100%);
}
/* Founder HARD CORRECTION 2026-05-03 — founder rule: "in dark mode,
   i can see a green square around the account icon in the desktop
   on the icons in the menu. remove it". The previous override drew
   a leaf-tinted gradient behind the account icon — kill it. Account
   icon now matches the other header icons (transparent bg, just
   the SVG). */
:root[data-theme="dark"] .tk-account-link {
  background: transparent !important;
  border-color: transparent !important;
  box-shadow: none !important;
}
/* Founder HARD CORRECTION 2026-05-03 — View Order button readable
   in both themes. Light mode: dark-leaf-deep bg + cream paper text
   (existing). Dark mode: --tk-leaf-deep collapses to the regular
   green and --tk-paper becomes dark gray, so text was unreadable
   on the green pill. Founder report: "TEXT ON VIEW ORDER BUTTON
   ISNT VISBLE". Override text to --tk-ink (high-contrast cream)
   in dark mode. */
:root[data-theme="dark"] .tk-order-view,
:root[data-theme="dark"] .tk-order-view:hover {
  color: var(--tk-ink) !important;
  background: color-mix(in srgb, var(--tk-leaf) 70%, var(--tk-paper-strong)) !important;
}

/* Founder HARD CORRECTION 2026-05-03 — comprehensive dark-mode
   surface fix block. Founder report (verbatim): "in dark mode,
   make the news carousel article backgrounds dark, the article
   background on the slider (where the text is), the background
   of the products inside the carousels still use white background,
   admin menu is still white". Each rule below points at a SPECIFIC
   element that was hardcoded to a white/cream rgba and ignored
   the dark theme. Light mode is untouched. */
/* Founder CORRECTION 2026-05-03 (rev 3) — REVERTED to original
   dark-mode card bg. Founder rule: leave the carousel ITEMS
   alone — they keep their card bg/border/shadow. The OVERLAY
   SHADOW the founder is hunting lives on the parent
   .tk-map-article-carousel section, not on the cards. */
:root[data-theme="dark"] .tk-map-article-card,
:root[data-theme="dark"] [data-tk-article-card] {
  background: var(--tk-paper) !important;
  color: var(--tk-ink);
}
/* Founder HARD CORRECTION 2026-05-03 — revert .tk-card bg.
   Founder rule: "i did NOT ask or tell you to put fucking
   container bullshit around product text. i like the fucking
   title and product info right on the background". So .tk-card
   STAYS transparent in dark mode — title/text reads directly on
   the page bg. Only .tk-card-art (the image tile) gets the dark
   gradient so the artwork swatch reads cleanly. */
/* Founder HARD CORRECTION 2026-05-03 (rev 2) — dark mode card-art
   also stays transparent. Founder rule: NO overlay behind product
   tiles in EITHER theme. SVG/PNG art renders directly on the page
   bg in light + dark. */
:root[data-theme="dark"] .tk-card-art {
  background: transparent !important;
  box-shadow: none !important;
}
/* Founder Admin / Demo Admin menu shell — was hardcoded #ffffff.
   Founder HARD CORRECTION 2026-05-03 (rev 2): scope tightened. The
   broad `:where(input, select, textarea, button)` selector inside
   the admin panel was overriding brand-coloured action buttons
   (Save Settings, Apply Storewide, etc.) and the menu nav buttons
   to a flat dark gray. Founder rule (verbatim): "MY MENU AND
   ADMIN SETTINGS AD DOING CRAYZ SHIT. MAKE UR EDITS NOT FUCKING
   TOUCH THOSE". Now we only repaint:
     - the panel SHELL (background/text)
     - text-style inputs (input[type=text|number|search|email|date],
       select, textarea) so the form fields are readable in dark mode
   Action BUTTONS keep whatever bg/color the existing rules set
   (green Save, etc.). */
:root[data-theme="dark"] .tk-demo-admin-menu,
:root[data-theme="dark"] [data-tk-demo-admin-menu],
:root[data-theme="dark"] [data-tk-founder-admin-panel] {
  background: var(--tk-paper) !important;
  color: var(--tk-ink) !important;
  border-color: var(--tk-line) !important;
}
:root[data-theme="dark"] .tk-demo-admin-menu :where(
  input[type="text"], input[type="number"], input[type="search"],
  input[type="email"], input[type="url"], input[type="date"],
  input[type="datetime-local"], input[type="time"], input[type="tel"],
  textarea, select
) {
  background: var(--tk-paper-strong);
  color: var(--tk-ink);
  border-color: var(--tk-line);
}
/* Founder rule "title and product info right on the background" —
   product/store/story/hero CARDS stay transparent in dark mode so
   the text reads on the page bg. Only the IMAGE/MEDIA tile inside
   each card gets a dark backdrop (handled by .tk-card-art above). */
/* The "play" / game-entry pill — founder reports it shows in dark
   but disappears in light. Light-mode rule was using a white-on-
   white treatment somewhere; pin it to a brand-colored background
   in BOTH themes so it stays visible. */
.tk-game-entry,
[data-tk-game-entry] {
  background: var(--tk-leaf) !important;
  color: var(--tk-ink, #fff) !important;
}
:root[data-theme="dark"] .tk-game-entry,
:root[data-theme="dark"] [data-tk-game-entry] {
  background: color-mix(in srgb, var(--tk-leaf) 70%, var(--tk-paper-strong)) !important;
  color: var(--tk-ink) !important;
}

/* Founder HARD CORRECTION 2026-05-03 — product size+quantity layout.
   Founder rule: "desktop products: move quantity select to the
   right of the amount selector". The size picker (1g / 3.5g / 7g
   buttons) and the qty stepper now share a flex row on DESKTOP.
   Mobile rule below pulls the stepper back NEXT TO Add to Cart
   per the founder's mobile-specific correction:
   "on mobile, the ADD TO CART button and the QUANTITY button are
   supposed to be on THE SAME ROW AS 'ADD TO CART'! Put those back
   on mobile". */
.tk-product-size-row {
  display: flex;
  align-items: end;
  gap: 14px;
  flex-wrap: wrap;
  margin: 8px 0 12px;
}
.tk-product-size-row .tk-product-size-picker {
  flex: 1 1 auto;
  min-width: 0;
}
.tk-product-size-row .tk-product-quantity {
  flex: 0 0 auto;
}
/* Founder HARD CORRECTION 2026-05-03 — clone visibility is viewport
   gated. Desktop hides the buy-row qty clone (qty stays in size-row);
   mobile flips it: hide the size-row qty, show the buy-row clone next
   to Add to Cart on the SAME line. Both inputs sync via JS. */
.tk-product-buy-row .tk-product-quantity-mobile-clone {
  display: none;
}
@media (max-width: 720px) {
  /* Mobile: send the qty stepper down to the buy row so it sits
     beside Add to Cart, matching the founder's mobile spec. The
     wrapper .tk-product-size-row keeps the size buttons by
     themselves above. */
  .tk-product-size-row {
    flex-wrap: nowrap;
  }
  .tk-product-size-row .tk-product-quantity {
    display: none !important;
  }
  .tk-product-buy-row {
    display: flex;
    flex-direction: row;
    align-items: stretch;
    gap: 10px;
    flex-wrap: nowrap;
  }
  .tk-product-buy-row .tk-product-add-cart {
    /* Founder HARD CORRECTION 2026-05-03 — base rule sets
       width: 100% which fights the flex layout and forces the
       qty stepper onto the next line. Force width: auto so the
       flex: 1 sizing wins; result: Add to Cart fills remaining
       space NEXT TO the qty stepper, not below it. */
    width: auto !important;
    flex: 1 1 0;
    min-width: 0;
  }
  .tk-product-buy-row .tk-product-quantity-mobile-clone {
    display: inline-flex;
    flex: 0 0 auto;
    align-items: center;
    /* compact stepper: tight pad so it fits on small phones */
    padding: 0 6px;
  }
  .tk-product-buy-row .tk-product-quantity-mobile-clone input {
    width: 36px;
    text-align: center;
  }
  .tk-product-buy-row .tk-product-quantity-mobile-clone button {
    width: 32px;
    height: 32px;
  }
}

/* Founder HARD CORRECTION 2026-05-03 — dark mode amount bubble
   readability. Founder rule: "in dark mode, make the selected
   amount button in products have amount bubbles have darker
   background — text isnt visible enough". Light-mode rule had
   bg=rgba(255,255,255,0.76) + color=var(--tk-ink) which becomes
   cream-on-cream in dark mode. Fix:
     - unselected: dark-paper bg + cream text
     - selected:   dark-leaf-mix bg + cream text
   Stepper also gets dark surface + light text. */
:root[data-theme="dark"] .tk-product-size-picker button {
  background: var(--tk-paper-strong) !important;
  color: var(--tk-ink) !important;
  border-color: var(--tk-line) !important;
}
:root[data-theme="dark"] .tk-product-size-picker button[data-active="true"] {
  background: color-mix(in srgb, var(--tk-leaf) 60%, var(--tk-paper-strong)) !important;
  color: var(--tk-ink) !important;
  border-color: var(--tk-leaf) !important;
}
:root[data-theme="dark"] .tk-product-quantity-stepper {
  background: var(--tk-paper-strong) !important;
  border-color: var(--tk-line) !important;
}
:root[data-theme="dark"] .tk-product-quantity input {
  color: var(--tk-ink) !important;
}
/* Map fade — the actual gradient lives on .tk-order-map::after
   (~line 1714) and starts at color-mix(in srgb, var(--tk-paper) 0%, transparent) (cream alpha 0).
   In dark mode that cream tint interpolates through and the fade
   reads as white instead of fading to dark. Override every map
   ::after / ::before variant. !important beats the original rule.
   Founder report: "the MAP DOESNT FADE TO BLACK AT THE BOTTOM, IT
   FADES TO WHITE STILL". */
:root[data-theme="dark"] .tk-order-map::after,
:root[data-theme="dark"] .tk-platform-map::after,
:root[data-theme="dark"] .tk-homepage-map::after,
:root[data-theme="dark"] [data-tk-platform-map]::after {
  background: linear-gradient(to bottom, color-mix(in srgb, var(--tk-bg) 0%, transparent), var(--tk-bg)) !important;
}
:root[data-theme="dark"] .tk-order-map::before,
:root[data-theme="dark"] .tk-platform-map::before,
:root[data-theme="dark"] .tk-homepage-map::before,
:root[data-theme="dark"] [data-tk-platform-map]::before {
  background: linear-gradient(to bottom, var(--tk-bg), transparent) !important;
}
/* The header bottom fade already uses var(--tk-header-surface) which
   IS dark in dark mode, but the founder reports it still renders
   light. Belt-and-suspenders: pin the fade explicitly to
   --tk-header-fade-strong → transparent so any future stylesheet
   that tries to overwrite it still lands on a dark hue. */
:root[data-theme="dark"] .tk-header::after,
:root[data-theme="dark"] .tk-header-shell::after {
  background: linear-gradient(180deg, var(--tk-header-fade-strong, rgba(42, 42, 42, 0.98)) 0%, transparent 100%);
}
/* Founder LIVE EDIT BLOCK 2026-04-30 (Google Maps test provider): when
   tileRoot mounts the Google Maps canvas, give it the full inset and
   clear any leftover OSM placeholder tint so the canvas reads cleanly.
   The marker layer (sibling of tileRoot) sits above with z-index handled
   by the existing markerRoot rules. */
.tk-platform-map-tiles[data-tk-google-maps-active] {
  background: transparent;
}
.tk-google-maps-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.tk-google-maps-canvas .gm-style { background: transparent !important; }
.tk-platform-map-tiles[data-tk-google-maps-active="loading"]::after {
  content: "Loading Google Maps…";
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: var(--tk-muted, #6f7a6e);
  font-size: 12px;
  background: var(--tk-paper, #f7f5f0);
}
.tk-platform-map-tiles[data-tk-google-maps-active="error"]::after {
  content: attr(data-tk-google-maps-error);
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 16px;
  text-align: center;
  color: var(--tk-warm, #c2773d);
  font-size: 12px;
  background: color-mix(in srgb, var(--tk-paper) 92%, transparent);
}
.tk-platform-map-attribution {
  position: absolute;
  z-index: 5;
  right: 58px;
  bottom: 10px;
  padding: 2px 6px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.78);
  color: var(--tk-ink-soft);
  font-size: 9px;
  font-weight: 800;
}
.tk-platform-map-grid {
  position: absolute;
  inset: -10%;
  opacity: 0.16;
  background:
    linear-gradient(90deg, color-mix(in srgb, var(--tk-leaf-deep) 10%, transparent) 1px, transparent 1px),
    linear-gradient(0deg, color-mix(in srgb, var(--tk-leaf-deep) 10%, transparent) 1px, transparent 1px);
  background-size: 34px 34px;
  /* Decorative lattice — must never absorb touches. Without this, the
     grid sat on top of the Google Maps canvas and silently blocked
     drag/pinch/zoom. */
  pointer-events: none;
}
/* When Google Maps is the active provider, hide the OSM-era grid
   entirely. It's redundant with Google's own tiles and can introduce
   visual moiré with Google's labels. */
[data-tk-google-maps-active] .tk-platform-map-grid,
[data-tk-google-maps-active] ~ .tk-platform-map-grid {
  display: none;
}
.tk-platform-map-grid::after {
  content: none;
}
body[data-tk-map-overlay-test="true"] .tk-platform-map-grid {
  opacity: 0.24;
  background:
    radial-gradient(circle at 22% 32%, color-mix(in srgb, var(--tk-leaf-light) 18%, transparent), transparent 26%),
    linear-gradient(90deg, color-mix(in srgb, var(--tk-leaf-deep) 12%, transparent) 1px, transparent 1px),
    linear-gradient(0deg, color-mix(in srgb, var(--tk-leaf-deep) 12%, transparent) 1px, transparent 1px);
  background-size: auto, 32px 32px, 32px 32px;
}
.tk-platform-map-markers {
  position: absolute;
  inset: 0;
  /* Marker layer sits on top of the map tiles / Google canvas. Without
     pointer-events:none, this container absorbs every touch and click,
     blocking drag/pinch/zoom from ever reaching the underlying map.
     Individual markers (.tk-map-marker) are already pointer-events:none,
     and any future clickable marker can opt in by setting
     pointer-events:auto on itself. */
  pointer-events: none;
}
.tk-map-marker {
  position: absolute;
  z-index: 2;
  width: 48px;
  transform: translate(-50%, -50%);
  display: grid;
  justify-items: center;
  gap: 3px;
  color: var(--tk-leaf-deep);
  pointer-events: none;
}
/* Founder HARD CORRECTION 2026-05-03 — customer pin stays SCREEN-FIXED
   at map-div center while the map drags freely. Founder rule:
   "MAPS MUST BE MOVEABLE AND ZOOMABLE, BUT THE PIN STAYS FUCKING STILL".
   Overrides the inline left/top set by renderMapPoint AND the
   reproject loop's translate3d (the customer marker is now excluded
   from that loop so this rule wins). Store/business pins still use
   the inline left/top + reproject path, so they stay glued to their
   real-world latitude/longitude. */
.tk-platform-map-markers .tk-map-marker.tk-map-customer,
.tk-platform-map-markers .tk-map-marker[data-marker-kind="customer"] {
  position: absolute !important;
  left: 50% !important;
  top: 50% !important;
  z-index: 4;
  transform: translate(-50%, -50%) !important;
}
.tk-map-marker::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 58px;
  height: 72px;
  transform: translate(-50%, -56%);
  z-index: -2;
  border-radius: 50% 50% 56% 56%;
  background:
    radial-gradient(circle at 50% 34%, color-mix(in srgb, var(--tk-map-pin-color, var(--tk-leaf)) 28%, transparent) 0 34%, transparent 60%),
    radial-gradient(ellipse at 50% 78%, color-mix(in srgb, var(--tk-map-pin-tail-color, var(--tk-leaf)) 24%, transparent) 0 28%, transparent 62%);
  clip-path: polygon(50% 0%, 76% 10%, 92% 34%, 84% 58%, 50% 100%, 16% 58%, 8% 34%, 24% 10%);
  filter: blur(6px);
  opacity: 0.9;
}
.tk-map-logo {
  position: relative;
  width: 42px;
  height: 42px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px 999px 999px 999px;
  background:
    radial-gradient(circle at 35% 22%, rgba(255,255,255,0.52), transparent 32%),
    linear-gradient(135deg, var(--tk-map-pin-color, var(--tk-leaf-deep)), var(--tk-map-pin-tail-color, var(--tk-leaf-deep)));
  border: 2px solid rgba(255, 255, 255, 0.88);
  box-shadow: 0 10px 24px color-mix(in srgb, var(--tk-leaf-deep) 18%, transparent), inset 0 1px 0 rgba(255,255,255,0.32);
  font-size: 10px;
  font-weight: 900;
  letter-spacing: -0.03em;
  overflow: visible;
}
.tk-map-logo::before {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -10px;
  width: 18px;
  height: 18px;
  background: var(--tk-map-pin-tail-color, var(--tk-leaf-deep));
  border-right: 2px solid rgba(255,255,255,0.88);
  border-bottom: 2px solid rgba(255,255,255,0.88);
  border-radius: 0 0 4px 0;
  transform: translateX(-50%) rotate(45deg);
  z-index: -1;
}
.tk-map-logo-img {
  position: relative;
  z-index: 2;
  width: 29px;
  height: 29px;
  object-fit: contain;
  padding: 3px;
  border-radius: 999px;
  background: rgba(255,255,255,0.94);
  filter: drop-shadow(0 2px 3px color-mix(in srgb, var(--tk-leaf-deep) 18%, transparent));
}
.tk-map-customer .tk-map-logo {
  border-color: rgba(201, 156, 58, 0.42);
  box-shadow: 0 12px 28px color-mix(in srgb, var(--tk-leaf-deep) 20%, transparent);
}
.tk-map-customer::before {
  background:
    radial-gradient(circle at 50% 34%, color-mix(in srgb, var(--tk-map-customer-glow, rgba(201, 156, 58, 0.32)) 38%, transparent) 0 34%, transparent 60%),
    radial-gradient(ellipse at 50% 78%, color-mix(in srgb, var(--tk-map-customer-glow, rgba(201, 156, 58, 0.32)) 26%, transparent) 0 28%, transparent 62%);
}
.tk-map-logo::after {
  content: none;
}
.tk-map-company[data-pulse="true"] .tk-map-logo,
.tk-map-driver-car[data-pulse="true"] .tk-map-car {
  animation: tkOrderMarkerPulse 1.28s ease-in-out infinite;
}
.tk-map-order-company[data-order-marker-state="pairing"]::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 48%;
  width: 70px;
  height: 82px;
  transform: translate(-50%, -56%);
  z-index: -3;
  border-radius: 46% 46% 54% 54%;
  border: 2px solid color-mix(in srgb, var(--tk-leaf) 48%, transparent);
  clip-path: polygon(50% 0%, 76% 10%, 92% 34%, 84% 58%, 50% 100%, 16% 58%, 8% 34%, 24% 10%);
  animation: tkOrderPinSearchRipple 1.35s ease-out infinite;
}
.tk-map-order-check {
  position: absolute;
  left: -12px;
  bottom: -11px;
  color: var(--tk-leaf);
  width: 32px;
  height: 32px;
  filter: drop-shadow(0 2px 0 var(--tk-paper)) drop-shadow(0 8px 14px color-mix(in srgb, var(--tk-leaf-deep) 28%, transparent));
}
.tk-map-order-check svg {
  width: 100%;
  height: 100%;
  display: block;
}
.tk-map-driver-car {
  width: 58px;
  color: var(--tk-leaf-deep);
}
.tk-map-car {
  width: 52px;
  height: 34px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--tk-leaf-deep);
  filter: drop-shadow(0 12px 18px color-mix(in srgb, var(--tk-leaf-deep) 28%, transparent));
}
.tk-map-car svg {
  width: 52px;
  height: 34px;
}
.tk-map-company-mini {
  position: absolute;
  top: -34px;
  left: 50%;
  transform: translateX(-50%) scale(0.68);
  transform-origin: center bottom;
  z-index: 3;
}
.tk-map-company-mini .tk-map-logo {
  box-shadow: 0 8px 18px color-mix(in srgb, var(--tk-leaf-deep) 18%, transparent);
}
@keyframes tkOrderPinSearchRipple {
  0% { opacity: 0.58; transform: translate(-50%, -56%) scale(0.78); }
  100% { opacity: 0; transform: translate(-50%, -56%) scale(1.18); }
}
.tk-map-marker[data-verified="true"] .tk-map-logo {
  animation: tkLogoFlagBadgeWave 4.8s ease-in-out infinite, tkStorePulse 1.25s ease-in-out infinite;
}
.tk-map-verified {
  position: absolute;
  top: -6px;
  right: -6px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--tk-verified-green);
  color: var(--tk-paper);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  font-weight: 900;
}
.tk-map-label {
  max-width: 92px;
  padding: 2px 6px;
  border-radius: 999px;
  background: rgba(255,255,255,0.9);
  color: var(--tk-ink);
  font-size: 10px;
  font-weight: 800;
  white-space: nowrap;
  box-shadow: 0 8px 18px color-mix(in srgb, var(--tk-leaf-deep) 10%, transparent);
}
.tk-map-rating {
  color: var(--tk-warm);
  font-weight: 900;
}
@keyframes tkOrderMarkerPulse {
  0%, 100% {
    scale: 1;
    filter: drop-shadow(0 10px 18px color-mix(in srgb, var(--tk-leaf-deep) 22%, transparent));
  }
  50% {
    scale: 1.08;
    filter: drop-shadow(0 14px 28px color-mix(in srgb, var(--tk-leaf) 36%, transparent));
  }
}
.tk-map-user-area .tk-map-logo {
  border-radius: 999px;
  background: var(--tk-paper);
  color: var(--tk-ink);
}
.tk-platform-map-zoom {
  position: absolute;
  z-index: 5;
  right: 12px;
  top: 50%;
  transform: translateY(-50%);
  display: grid;
  gap: 7px;
}
.tk-platform-map-zoom button {
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: 12px;
  background: color-mix(in srgb, var(--tk-leaf-deep) 88%, transparent);
  color: var(--tk-paper);
  font: 900 18px/1 var(--tk-font-sans);
  cursor: pointer;
  box-shadow: 0 10px 24px color-mix(in srgb, var(--tk-leaf-deep) 18%, transparent);
}
.tk-platform-map-privacy {
  position: absolute;
  z-index: 5;
  left: 12px;
  right: 190px;
  bottom: 10px;
  margin: 0;
  color: var(--tk-ink-soft);
  font-size: 10px;
  line-height: 1.25;
  text-wrap: balance;
}
/* Founder LIVE EDIT 2026-05-01 (news carousel container transparency):
   The mount-div wrapping both the homepage map hero and the carousel
   must have no background of its own. Without this, the body bg color
   leaks through the gap between carousel cards in the overlap zone,
   showing as a dark strip between cards. Transparent here lets the map
   tiles show through those gaps instead. */
[data-tk-homepage-map-hero-mount] {
  background: transparent;
}
.tk-map-article-carousel {
  order: -19;
  width: var(--tk-map-hero-article-width);
  max-width: var(--tk-map-hero-article-width);
  margin: calc(-1 * var(--tk-map-hero-article-overlap)) auto 0;
  position: relative;
  z-index: 8;
  pointer-events: none;
}
.tk-map-article-track {
  display: flex;
  flex-wrap: nowrap;
  align-items: flex-start;
  gap: calc(var(--tk-article-card-gap, 14px) * var(--tk-article-card-scale, 1));
  overflow-x: auto;
  scroll-snap-type: none;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
  touch-action: pan-x;
  /* Founder direct correction 2026-04-29: no website scroll-snap rules.
     Refreshes on homepage/order routes must never snap down to the map/game. */
  padding: 0 0 8px;
  scrollbar-width: none;
  pointer-events: auto;
  /* Founder zero-blocker visual repair 2026-04-30: the news/guide carousel must
     fade left/right to transparency so it sits cleanly over the map without a
     dark backdrop strip. Mask width is config-fed via
     homepage_rows.mapHeroArticleCarousel.edgeFadeWidth and applied here so the
     carousel viewport itself is what fades — not the cards. */
  -webkit-mask-image: linear-gradient(
    to right,
    transparent 0,
    #000 var(--tk-map-hero-article-edge-fade-width, 58px),
    #000 calc(100% - var(--tk-map-hero-article-edge-fade-width, 58px)),
    transparent 100%
  );
          mask-image: linear-gradient(
    to right,
    transparent 0,
    #000 var(--tk-map-hero-article-edge-fade-width, 58px),
    #000 calc(100% - var(--tk-map-hero-article-edge-fade-width, 58px)),
    transparent 100%
  );
}
/* Founder zero-blocker visual repair 2026-04-30 + LIVE EDIT BLOCK 2026-04-30
   (item 1 — remove dark overlay behind news EVERYWHERE): the news/article
   carousel never gets a dark backdrop strip. Both the conditional body-attr
   path and the unconditional path null the ::before/::after pseudo-elements
   and force the carousel container's own background to transparent so any
   stray dark overlay from a third-party stylesheet can't leak through. The
   carousel cards still render their own backgrounds; only the rectangular
   strip BEHIND them is permanently disabled. */
.tk-map-article-carousel { background: transparent !important; }
.tk-map-article-carousel::before,
.tk-map-article-carousel::after,
body[data-tk-map-article-backdrop="false"] .tk-map-article-carousel::before,
body[data-tk-map-article-backdrop="false"] .tk-map-article-carousel::after {
  content: none !important;
  background: transparent !important;
  display: none !important;
}
.tk-map-article-track::-webkit-scrollbar { display: none; }
.tk-map-article-card-frame {
  flex: 0 0 calc(var(--tk-article-card-width, 460px) * var(--tk-article-card-scale, 1));
  width: calc(var(--tk-article-card-width, 460px) * var(--tk-article-card-scale, 1));
  height: calc(var(--tk-article-card-height, 192px) * var(--tk-article-card-scale, 1));
  position: relative;
  overflow: visible;
  pointer-events: auto;
}
.tk-map-article-card {
  /* Founder LIVE EDIT BLOCK 2026-04-30 (item 3 — remove black overlay
     behind news carousel): the previous heavy shadow
     (0 28px 68px color-mix(in srgb, var(--tk-leaf-deep) 22%, transparent)) pooled a dark wash directly under
     each card, which is what Founder was seeing as the "black overlay
     behind the news carousel". The shadow strength is now CSS-var-
     driven (--tk-map-article-card-shadow), defaults to a subtle lift
     instead of a heavy panel-shaped wash. JSON
     (homepage_rows.mapHeroArticleCarousel.cardShadow) drives the var
     so it stays config-owned. The carousel itself, its ::before/::after,
     and any parent backdrop are already nulled to transparent in the
     rules immediately above. */
  /* Founder CORRECTION 2026-05-03 (rev 4) — keep bg + border on
     the article card (the founder wants the white-card look),
     but kill the box-shadow that draws the dark halo behind each
     card. Founder rule: "THE FUCKING CAROUSEL ITEMS HAVE AN
     OVERLAY SHADOW!!! LEAVE THE FUCKING CAROUSEL ITEMS ALONE
     THEMSELVES" — interpreted as: leave the card surface alone,
     just remove the surrounding shadow. */
  width: var(--tk-article-card-width, 460px);
  height: var(--tk-article-card-height, 192px);
  display: grid;
  grid-template-columns: minmax(0, 38%) minmax(0, 1fr);
  align-items: stretch;
  overflow: hidden;
  border-radius: var(--tk-article-card-radius, 24px);
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 13%, transparent);
  /* Founder HARD CORRECTION 2026-05-03 — founder rule: "MAKE PURE
     FUCKING COLOR". rgba(255,255,255,0.95) was translucent; now
     solid var(--tk-paper) (cream in light, dark gray in dark). */
  background: var(--tk-paper);
  color: var(--tk-ink);
  text-decoration: none;
  box-shadow: none;
  transform: scale(var(--tk-article-card-scale, 1));
  transform-origin: top left;
  box-sizing: border-box;
}
.tk-map-article-media {
  position: relative;
  display: block;
  min-height: 100%;
  overflow: hidden;
  background: var(--tk-leaf-soft);
}
.tk-map-article-media svg {
  width: 100%;
  height: 100%;
  display: block;
}
.tk-map-article-copy {
  display: grid;
  align-content: center;
  gap: 8px;
  padding: clamp(18px, 2.6vw, 34px);
}
.tk-map-article-copy small {
  color: var(--tk-warm);
  font-size: 11px;
  font-weight: 950;
  letter-spacing: .14em;
  text-transform: uppercase;
}
.tk-map-article-copy strong {
  color: var(--tk-leaf-deep);
  font-size: clamp(22px, 3vw, 42px);
  line-height: .98;
  letter-spacing: -0.05em;
}
.tk-map-article-copy em {
  color: var(--tk-ink-soft);
  font-size: clamp(13px, 1.4vw, 16px);
  font-style: normal;
  line-height: 1.35;
}
@keyframes tkStorePulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--tk-leaf) 34%, transparent), 0 8px 22px rgba(20, 20, 18, 0.2); }
  50% { box-shadow: 0 0 0 12px color-mix(in srgb, var(--tk-leaf) 0%, transparent), 0 8px 22px rgba(20, 20, 18, 0.24); }
}

.tk-order-detail {
  display: grid;
  gap: 14px;
  padding: 18px;
  border-radius: 22px;
  background: var(--tk-paper);
  border: 1px solid var(--tk-line);
}
.tk-order-detail[hidden] { display: none; }
.tk-order-detail-head { display: grid; gap: 4px; text-align: center; }
.tk-order-detail-head h2,
.tk-order-detail-head p { margin: 0; }
.tk-order-detail-head p:last-child { color: var(--tk-muted); font-size: 13px; }

/* Order detail route guard. Founder correction 2026-04-28: /demo/orders/*
   keeps the shared order status and embedded game, then the receipt is the
   final page content. Do not rely only on the hidden attribute here because
   the homepage row CSS sets display:grid and can override UA [hidden] rules. */
body.tk-order-page .tk-row,
body.tk-order-page .tk-footer {
  display: none !important;
}
body.tk-client-order-view .tk-play-head,
body.tk-client-order-view .tk-play-frame {
  display: none !important;
}
.tk-client-order-view {
  order: var(--tk-order-desktop-play-head-order, 5);
  display: grid;
  gap: 14px;
  padding: 18px;
  border-radius: 24px;
  background: linear-gradient(145deg, rgba(255,255,255,.74), rgba(239,248,234,.86));
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 12%, transparent);
}
.tk-client-order-view[hidden] {
  display: none !important;
}
.tk-client-order-view header {
  display: grid;
  gap: 4px;
}
.tk-client-order-view h3,
.tk-client-order-view p {
  margin: 0;
}
.tk-client-order-lifecycle {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.tk-client-order-lifecycle span,
.tk-client-confirmation-grid article {
  border-radius: 16px;
  background: color-mix(in srgb, var(--tk-leaf-deep) 7%, transparent);
  color: var(--tk-ink-soft);
  padding: 9px 11px;
  font-size: 12px;
  font-weight: 850;
}
.tk-client-order-lifecycle span[data-on="true"] {
  background: color-mix(in srgb, var(--tk-leaf) 17%, transparent);
  color: var(--tk-leaf-deep);
}
.tk-client-confirmation-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}
.tk-client-confirmation-grid article {
  display: grid;
  gap: 5px;
}
.tk-client-confirmation-grid span {
  color: var(--tk-muted);
  font-size: 12px;
}
.tk-client-photo-thumb {
  width: 72px;
  height: 54px;
  border-radius: 12px;
  background: radial-gradient(circle at 45% 42%, #bff48d, transparent 24%), linear-gradient(145deg, #132719, #09120c);
}
.tk-order-dashboard,
.tk-client-business-dashboard {
  display: grid;
  gap: 16px;
  margin-top: 18px;
  padding: clamp(16px, 2.8vw, 24px);
  border-radius: 24px;
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 12%, transparent);
  background:
    radial-gradient(circle at 92% 10%, color-mix(in srgb, var(--tk-leaf) 13%, transparent), transparent 30%),
    linear-gradient(145deg, rgba(255,255,255,.82), rgba(241,249,236,.9));
  box-shadow: 0 18px 42px color-mix(in srgb, var(--tk-leaf-deep) 8%, transparent);
}
.tk-order-dashboard-head,
.tk-client-dashboard-head {
  display: flex;
  justify-content: space-between;
  gap: 14px;
  align-items: start;
}
.tk-order-dashboard-head h2,
.tk-order-dashboard-head p,
.tk-client-dashboard-head h2,
.tk-client-dashboard-head p {
  margin: 0;
}
.tk-order-dashboard-head label,
.tk-client-dashboard-controls label {
  display: grid;
  gap: 5px;
  color: var(--tk-muted);
  font-size: 11px;
  font-weight: 900;
  letter-spacing: .08em;
  text-transform: uppercase;
}
.tk-order-dashboard-head input,
.tk-client-dashboard-controls select {
  min-height: 38px;
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 14%, transparent);
  border-radius: 13px;
  background: rgba(255,255,255,.82);
  color: var(--tk-ink);
  font: 800 13px/1.2 var(--tk-font-sans);
  padding: 0 12px;
}
.tk-order-dashboard-shell {
  display: grid;
  grid-template-columns: minmax(210px, .34fr) minmax(0, 1fr);
  gap: 14px;
  min-height: 420px;
}
.tk-order-dashboard-list {
  display: grid;
  align-content: start;
  gap: 8px;
  max-height: 520px;
  overflow: auto;
  padding-right: 3px;
}
.tk-order-dashboard-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  position: sticky;
  top: 0;
  z-index: 1;
  padding-bottom: 6px;
  background: linear-gradient(180deg, rgba(246,250,241,.96), rgba(246,250,241,.72));
}
.tk-order-dashboard-filters span {
  border-radius: 999px;
  padding: 5px 8px;
  background: color-mix(in srgb, var(--tk-leaf) 12%, transparent);
  color: var(--tk-leaf-deep);
  font-size: 10px;
  font-weight: 900;
}
.tk-order-dashboard-list button {
  display: grid;
  gap: 3px;
  width: 100%;
  text-align: left;
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 10%, transparent);
  border-radius: 16px;
  padding: 11px;
  background: rgba(255,255,255,.72);
  color: var(--tk-ink);
  cursor: pointer;
}
.tk-order-dashboard-list button[data-active="true"] {
  background: linear-gradient(135deg, color-mix(in srgb, var(--tk-leaf-deep) 94%, transparent), color-mix(in srgb, var(--tk-leaf) 90%, transparent));
  color: var(--tk-paper);
}
.tk-order-dashboard-list small,
.tk-order-dashboard-list span {
  color: inherit;
  opacity: .75;
}
.tk-order-dashboard-detail {
  display: grid;
  gap: 14px;
  min-height: 100%;
  border-radius: 20px;
  padding: 16px;
  background: rgba(255,255,255,.78);
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 10%, transparent);
}
.tk-order-dashboard-detail[hidden] {
  display: none !important;
}
.tk-order-dashboard-detail header {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  align-items: start;
}
.tk-order-dashboard-detail h2,
.tk-order-dashboard-detail h3,
.tk-order-dashboard-detail p {
  margin: 0;
}
.tk-order-dashboard-grid,
.tk-client-dashboard-metrics {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 10px;
}
.tk-order-dashboard-grid article,
.tk-client-dashboard-metrics article {
  display: grid;
  gap: 4px;
  padding: 12px;
  border-radius: 16px;
  background: color-mix(in srgb, var(--tk-leaf-deep) 6%, transparent);
}
.tk-order-dashboard-grid small,
.tk-client-dashboard-metrics span {
  color: var(--tk-muted);
  font-size: 10px;
  font-weight: 900;
  letter-spacing: .09em;
  text-transform: uppercase;
}
.tk-order-dashboard-grid span,
.tk-order-dashboard-columns p,
.tk-order-dashboard-columns li,
.tk-order-dashboard-columns dd,
.tk-client-dashboard-metrics strong,
.tk-client-dashboard-table span,
.tk-client-stripe-note span {
  color: var(--tk-ink-soft);
  font-size: 12px;
}
.tk-order-dashboard-columns {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px;
}
.tk-order-dashboard-columns section {
  border-radius: 16px;
  background: color-mix(in srgb, var(--tk-leaf-deep) 4%, transparent);
  padding: 12px;
}
.tk-order-dashboard-columns ul,
.tk-order-dashboard-columns ol {
  margin: 8px 0 0;
  padding-left: 18px;
}
.tk-order-dashboard-columns dl {
  display: grid;
  gap: 5px;
  margin: 8px 0 0;
}
.tk-order-dashboard-columns dl div {
  display: flex;
  justify-content: space-between;
  gap: 10px;
}
.tk-client-dashboard-controls {
  display: grid;
  justify-items: end;
  gap: 9px;
}
.tk-client-dashboard-controls div[role="group"] {
  display: flex;
  gap: 6px;
}
.tk-client-dashboard-controls button {
  border: 0;
  border-radius: 999px;
  padding: 8px 10px;
  background: color-mix(in srgb, var(--tk-leaf-deep) 8%, transparent);
  color: var(--tk-leaf-deep);
  font-weight: 900;
  cursor: pointer;
}
.tk-client-dashboard-controls button[data-active="true"] {
  background: var(--tk-leaf-deep);
  color: var(--tk-paper);
}
.tk-client-dashboard-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(255px, 1fr));
  gap: 12px;
}
.tk-client-dashboard-section {
  display: grid;
  gap: 10px;
  border-radius: 18px;
  padding: 14px;
  background: rgba(255,255,255,.74);
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 10%, transparent);
}
.tk-client-dashboard-section h3 {
  margin: 0;
  color: var(--tk-leaf-deep);
}
.tk-client-dashboard-table {
  display: grid;
  gap: 6px;
  overflow: auto;
}
.tk-client-dashboard-table > div {
  display: grid;
  grid-template-columns: repeat(6, minmax(92px, 1fr));
  gap: 6px;
  min-width: 620px;
}
.tk-client-dashboard-table strong,
.tk-client-dashboard-table span {
  padding: 8px;
  border-radius: 10px;
  background: color-mix(in srgb, var(--tk-leaf-deep) 6%, transparent);
}
.tk-client-stripe-note {
  display: grid;
  gap: 4px;
  border-radius: 16px;
  padding: 12px;
  background: color-mix(in srgb, var(--tk-warm) 12%, transparent);
  color: var(--tk-ink-soft);
}
.tk-demo-admin-menu {
  /* Founder LIVE EDIT 2026-05-01 RE-RUN PASS #3 — Founder Admin shell
     redesign. Founder: "redesign it to match TikToke UI", "every
     section usable, fitted, and polished".
     Founder LIVE EDIT 2026-05-01 (URGENT MOBILE TAP+SCROLL FIX):
     z-index lifted from 43 → 4500 because the strict z-index
     hierarchy pass moved the header to 4000. Any element that
     stacks above the admin panel intercepts touches on mobile,
     which is what broke tap+scroll. 4500 sits above the header
     (4000) and below the privacy banner (5000) — admin remains
     below modals (gate 9000+, popups 8500) but above page chrome.
     pointer-events: auto + touch-action: pan-y are explicit so no
     ancestor or sibling rule can disable touches. */
  position: fixed;
  left: max(14px, env(safe-area-inset-left, 0px));
  bottom: max(14px, env(safe-area-inset-bottom, 0px));
  z-index: 4500;
  pointer-events: auto;
  touch-action: pan-y;
  display: grid;
  gap: 6px;
  width: min(320px, calc(100vw - 28px));
  max-width: calc(100vw - 28px);
  /* Pass: WEBSITE-ADMIN-COMMAND-CENTRE — bounded panel height. dvh
     (dynamic viewport height) avoids iOS Safari's mobile address-bar
     swing that previously made the panel feel oversized. Desktop fall-
     back via vh for non-dvh browsers. Mobile cap (74dvh) is enforced
     in the media query below; desktop cap stays at 80vh. */
  max-height: var(--tk-demo-admin-panel-max-height, 80vh);
  max-height: var(--tk-demo-admin-panel-max-height, 80dvh);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  box-sizing: border-box;
  grid-template-columns: minmax(0, 1fr);
  padding: 14px 14px 12px;
  border-radius: 16px;
  /* Founder screenshot evidence: at 96% opacity the page background
     bled through and sections looked flat. Going FULLY OPAQUE white
     so the admin reads as a real product surface, not a translucent
     overlay. Drop shadow upgraded for elevation hierarchy. */
  background: #ffffff;
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 14%, transparent);
  box-shadow:
    0 1px 2px rgba(20, 20, 18, 0.04),
    0 8px 16px rgba(20, 20, 18, 0.10),
    0 24px 48px rgba(20, 20, 18, 0.14);
  font-family: var(--tk-font-sans, "Inter", system-ui, sans-serif);
}
/* Distinct titlebar — Founder: "must look like polished TikToke admin
   tool / clean header 'Founder Admin' + 'Live platform controls'". */
.tk-demo-admin-menu .tk-demo-admin-titlebar {
  padding: 4px 4px 10px;
  border-bottom: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 10%, transparent);
}
.tk-demo-admin-menu .tk-demo-admin-title {
  color: var(--tk-leaf-deep, var(--tk-leaf-deep, #1f3d2c));
  font-size: 15px;
  font-weight: 800;
  letter-spacing: -0.01em;
}
.tk-demo-admin-menu .tk-demo-admin-subtitle {
  color: var(--tk-muted, #6f7a6e);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.02em;
  margin-top: 2px;
}
/* Section cards rendered with clear cream-tinted background so each
   section reads as a distinct "card" instead of a flat row. */
.tk-demo-admin-menu .tk-demo-admin-section {
  background: var(--tk-paper);
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 8%, transparent);
}
.tk-demo-admin-menu .tk-demo-admin-section[open] {
  background: #ffffff;
  border-color: var(--tk-leaf, var(--tk-leaf, #3a8f5a));
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--tk-leaf) 18%, transparent);
}
.tk-demo-admin-menu .tk-demo-admin-summary {
  color: var(--tk-leaf-deep, var(--tk-leaf-deep, #1f3d2c));
}
.tk-demo-admin-menu .tk-demo-admin-section-body label {
  display: grid;
  gap: 4px;
  font-size: 12px;
  color: var(--tk-leaf-deep, var(--tk-leaf-deep, #1f3d2c));
}
/* Form-control polish so inputs/selects feel native rather than
   raw browser defaults. */
.tk-demo-admin-menu input[type="text"],
.tk-demo-admin-menu input[type="number"],
.tk-demo-admin-menu input[type="search"],
.tk-demo-admin-menu select {
  width: 100%;
  box-sizing: border-box;
  padding: 7px 10px;
  font-size: 13px;
  font-family: inherit;
  color: var(--tk-leaf-deep, var(--tk-leaf-deep, #1f3d2c));
  background: #ffffff;
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 18%, transparent);
  border-radius: 8px;
  outline: none;
  transition: border-color 0.12s, box-shadow 0.12s;
}
.tk-demo-admin-menu input[type="text"]:focus,
.tk-demo-admin-menu input[type="number"]:focus,
.tk-demo-admin-menu input[type="search"]:focus,
.tk-demo-admin-menu select:focus {
  border-color: var(--tk-leaf, var(--tk-leaf, #3a8f5a));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--tk-leaf) 18%, transparent);
}
.tk-demo-admin-menu .tk-demo-admin-field {
  display: grid;
  gap: 4px;
}
.tk-demo-admin-menu .tk-demo-admin-field > span {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--tk-muted, #6f7a6e);
}
/* Primary button (Save / Apply) matches TikToke leaf-deep brand
   instead of flat browser default. */
.tk-demo-admin-menu button.tk-demo-admin-primary,
.tk-demo-admin-menu [data-tk-demo-admin-apply],
.tk-demo-admin-menu [data-tk-spin-wheel-save],
.tk-demo-admin-menu [data-tk-logo-save] {
  background: var(--tk-leaf-deep, var(--tk-leaf-deep, #1f3d2c));
  color: var(--tk-paper, #f7f5f0);
  border: 1px solid var(--tk-leaf-deep, var(--tk-leaf-deep, #1f3d2c));
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: 8px 12px;
  border-radius: 8px;
  cursor: pointer;
  transition: background 0.12s, transform 0.12s;
}
.tk-demo-admin-menu button.tk-demo-admin-primary:hover,
.tk-demo-admin-menu [data-tk-demo-admin-apply]:hover,
.tk-demo-admin-menu [data-tk-spin-wheel-save]:hover,
.tk-demo-admin-menu [data-tk-logo-save]:hover {
  background: var(--tk-leaf, var(--tk-leaf, #3a8f5a));
  transform: translateY(-1px);
}
.tk-demo-admin-menu[hidden] {
  display: none !important;
}
/* Founder LIVE EDIT 2026-04-30 (USE homepage Founder Admin panel as main
   on Account): the embedded version of the panel inherits all the inner
   section styling but has its floating-pill positioning + size cap
   neutralized so it flows naturally inside the .tk-account-panel-body
   accordion. position:static and width:100% drop the fixed-bottom-left
   anchor; max-height and overflow are released because the surrounding
   accordion handles overflow on its own; box-shadow + backdrop-filter
   are removed because the embedded surface sits flat on the account
   page background. */
.tk-demo-admin-menu.tk-demo-admin-menu-embedded {
  position: static;
  inset: auto;
  left: auto;
  bottom: auto;
  width: 100%;
  min-width: 0;
  max-width: 100%;
  max-height: none;
  overflow: visible;
  box-shadow: none;
  backdrop-filter: none;
  background: transparent;
  border: 0;
  padding: 0;
  z-index: auto;
}
.tk-demo-admin-menu.tk-demo-admin-menu-embedded .tk-demo-admin-titlebar {
  /* embedded inside the account "Founder Admin" accordion which already
     has its own title — hide the duplicate inner titlebar so the
     accordion summary stays the only header */
  display: none;
}
.tk-demo-admin-menu strong {
  color: var(--tk-leaf-deep);
  font-size: 13px;
}
.tk-demo-admin-menu select,
.tk-demo-admin-menu button {
  /* Founder LIVE EDIT 2026-04-30 (founder admin text fit): the prior
     overflow:hidden + text-overflow:ellipsis cut off legitimate labels
     like "Save desktop logo geometry" / "Apply for everyone" inside
     the narrow panel. Buttons now wrap to multiple lines (white-space:
     normal + word-break:break-word) so the full label is always
     readable; selects keep ellipsis (handled in the override below)
     because native select widgets don't accept multi-line option text
     without browser-specific hacks. */
  width: 100%;
  max-width: 100%;
  min-width: 0;
  box-sizing: border-box;
  inline-size: 100%;
  font: inherit;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 16%, transparent);
  padding: 8px 10px;
  text-align: center;
  line-height: 1.25;
}
.tk-demo-admin-menu button {
  white-space: normal;
  word-break: break-word;
  overflow-wrap: anywhere;
  border-radius: 12px;
  min-height: 34px;
}
.tk-demo-admin-menu select {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tk-demo-admin-menu .tk-demo-admin-link-button {
  white-space: normal;
  word-break: break-word;
  overflow-wrap: anywhere;
}
/* Founder LIVE EDIT BLOCK 2026-05-01 (collapsible Demo admin sections):
   each <details> reads as a clickable section row matching the account
   accordion style — clean summary header with chevron, expanded body
   with 8px gap, no fieldset border around logo controls. The panel
   stays narrow so the Founder pill doesn't overflow viewport. */
.tk-demo-admin-section {
  border: 1px solid var(--tk-line);
  border-radius: 12px;
  background: color-mix(in srgb, var(--tk-paper) 92%, transparent);
  overflow: hidden;
}
.tk-demo-admin-section + .tk-demo-admin-section { margin-top: 6px; }
.tk-demo-admin-summary {
  list-style: none;
  cursor: pointer;
  padding: 9px 12px;
  font-weight: 800;
  font-size: 12px;
  color: var(--tk-leaf-deep);
  display: flex;
  align-items: center;
  justify-content: space-between;
  user-select: none;
  /* Founder LIVE EDIT 2026-04-30 (founder admin text fit): summary text
     wraps to multiple lines when needed so consolidated labels like
     "Header / Menu / Logo Layout" fit the 270px panel without clipping.
     Min-width:0 inside the flex parent prevents the chevron from
     squeezing the text into ellipsis territory. */
  gap: 8px;
  white-space: normal;
  word-break: break-word;
  overflow-wrap: anywhere;
  line-height: 1.3;
  min-width: 0;
}
.tk-demo-admin-summary::-webkit-details-marker { display: none; }
.tk-demo-admin-summary::after {
  content: "▾";
  font-size: 10px;
  color: var(--tk-muted);
  transition: transform 0.18s ease;
  flex-shrink: 0;
}
.tk-demo-admin-section[open] .tk-demo-admin-summary::after {
  transform: rotate(180deg);
}
.tk-demo-admin-section-body {
  display: grid;
  gap: 8px;
  padding: 10px 12px 12px;
  border-top: 1px solid var(--tk-line);
}
.tk-demo-admin-title {
  display: block;
  margin-bottom: 4px;
}

/* Founder LIVE EDIT 2026-05-01 (REBUILD ADMIN MENUS — match existing UI
   exactly): the floating Founder Admin panel sections must mirror the
   gold-standard .tk-spin-admin-group used by Account → Founder Spin
   Wheel Settings (see styles.css:1886+). Below rules upgrade the
   collapsed/expanded card visuals to the same rounded-22px,
   leaf-soft-tinted, drop-shadow card with chevron-arrow summary that
   has h4 + p typography. The same selectors target both the floating
   pill (.tk-demo-admin-menu) AND the embedded Account version
   (.tk-demo-admin-menu-embedded) so the Account page automatically
   inherits the polished card look without a separate render path —
   one canonical CSS source of truth across surfaces. */
.tk-demo-admin-menu .tk-demo-admin-section,
.tk-demo-admin-menu .tk-demo-admin-subsection {
  display: grid;
  gap: 10px;
  padding: 12px 14px;
  border: 1px solid color-mix(in srgb, var(--tk-line) 86%, transparent);
  border-radius: 18px;
  background: color-mix(in srgb, var(--tk-paper) 88%, var(--tk-leaf-soft));
  box-shadow: 0 12px 28px rgba(20, 20, 18, 0.06);
  overflow: visible;
}
.tk-demo-admin-menu .tk-demo-admin-subsection {
  border-radius: 14px;
  padding: 10px 12px;
  background: color-mix(in srgb, var(--tk-paper) 96%, var(--tk-leaf-soft));
  box-shadow: 0 6px 14px rgba(20, 20, 18, 0.04);
}
.tk-demo-admin-menu .tk-demo-admin-section[open],
.tk-demo-admin-menu .tk-demo-admin-subsection[open] {
  background: var(--tk-paper, #fff);
  border-color: var(--tk-leaf, var(--tk-leaf, #3a8f5a));
  box-shadow:
    0 0 0 1px color-mix(in srgb, var(--tk-leaf) 18%, transparent),
    0 14px 32px rgba(20, 20, 18, 0.08);
}
.tk-demo-admin-menu .tk-demo-admin-section + .tk-demo-admin-section {
  margin-top: 10px;
}
.tk-demo-admin-menu .tk-demo-admin-subsection + .tk-demo-admin-subsection {
  margin-top: 8px;
}
.tk-demo-admin-menu .tk-demo-admin-summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 12px;
  padding: 0;
  border: 0;
  font-weight: inherit;
  font-size: inherit;
  color: inherit;
  user-select: none;
}
.tk-demo-admin-menu .tk-demo-admin-summary::-webkit-details-marker { display: none; }
.tk-demo-admin-menu .tk-demo-admin-summary::after {
  content: "";
  width: 9px;
  height: 9px;
  border-right: 2px solid var(--tk-leaf-deep);
  border-bottom: 2px solid var(--tk-leaf-deep);
  transform: rotate(45deg);
  transition: transform .18s ease;
  flex-shrink: 0;
  margin-top: 6px;
}
.tk-demo-admin-menu .tk-demo-admin-section[open] > .tk-demo-admin-summary::after,
.tk-demo-admin-menu .tk-demo-admin-subsection[open] > .tk-demo-admin-summary::after {
  transform: rotate(225deg);
}
.tk-demo-admin-menu .tk-demo-admin-summary > div {
  display: grid;
  gap: 3px;
  min-width: 0;
  flex: 1 1 auto;
}
.tk-demo-admin-menu .tk-demo-admin-summary h4 {
  margin: 0;
  font-size: 13px;
  font-weight: 800;
  color: var(--tk-leaf-deep);
  letter-spacing: -0.01em;
  white-space: normal;
  word-break: break-word;
  line-height: 1.25;
}
.tk-demo-admin-menu .tk-demo-admin-summary p {
  margin: 0;
  font-size: 11px;
  font-weight: 500;
  color: var(--tk-muted);
  line-height: 1.35;
}
.tk-demo-admin-menu .tk-demo-admin-section-body {
  display: grid;
  gap: 10px;
  padding: 0;
  border-top: 0;
}

/* Bottom-anchored Save / Apply for everyone — Founder: "Save / Apply
   section removed; Save + Apply for everyone buttons live at the
   bottom outside any section". Mirrors the Account page security
   action button pair (.tk-account-security-action) styling so all
   three surfaces feel native. */
.tk-demo-admin-menu .tk-demo-admin-bottom-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin-top: 6px;
  /* Pass: WEBSITE-ADMIN-COMMAND-CENTRE — sticky footer so Save and
     Apply Storewide are always reachable while the settings body
     scrolls. The panel itself is the scroll container; sticky binds
     to the last child of the scroll viewport. Opaque background so
     setting rows aren't visible bleeding through, safe-area padding
     so the iPhone home indicator can't cover the buttons. */
  position: sticky;
  bottom: 0;
  background: #ffffff;
  padding: 10px 0 calc(env(safe-area-inset-bottom, 0px) + 6px);
  border-top: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 10%, transparent);
  z-index: 6;
}
.tk-demo-admin-menu .tk-demo-admin-bottom-actions[data-tk-sticky="true"] {
  /* Subtle elevation so the sticky bar reads as floating above the
     scrolled content. Mobile + desktop both honor this. */
  box-shadow: 0 -8px 12px -8px rgba(20, 20, 18, 0.18);
}
/* Pass: WEBSITE-ADMIN-COMMAND-CENTRE — mobile panel cap at 74dvh per
   founder ("not too tall, must show sticky footer"). Account-embedded
   variants honor the same cap so the chat. surface doesn't overflow. */
@media (max-width: 720px) {
  .tk-demo-admin-menu {
    max-height: 74dvh;
    max-height: 74vh;
  }
}
.tk-demo-admin-menu .tk-demo-admin-bottom-actions [data-tk-founder-admin-save] {
  background: var(--tk-leaf-deep, var(--tk-leaf-deep, #1f3d2c));
  color: #fffaf1;
  border: 1px solid var(--tk-leaf-deep, var(--tk-leaf-deep, #1f3d2c));
  border-radius: 999px;
  padding: 10px 14px;
  font-weight: 800;
  font-size: 12px;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: background .12s, transform .12s;
}
.tk-demo-admin-menu .tk-demo-admin-bottom-actions [data-tk-founder-admin-apply] {
  background: color-mix(in srgb, var(--tk-leaf) 13%, transparent);
  color: var(--tk-leaf-deep, var(--tk-leaf-deep, #1f3d2c));
  border: 1px solid color-mix(in srgb, var(--tk-leaf) 26%, transparent);
  border-radius: 999px;
  padding: 10px 14px;
  font-weight: 800;
  font-size: 12px;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: background .12s, transform .12s;
}
.tk-demo-admin-menu .tk-demo-admin-bottom-actions [data-tk-founder-admin-save]:hover,
.tk-demo-admin-menu .tk-demo-admin-bottom-actions [data-tk-founder-admin-apply]:hover {
  transform: translateY(-1px);
}
.tk-demo-admin-menu .tk-demo-admin-bottom-actions [data-tk-founder-admin-status] {
  grid-column: 1 / -1;
  font-size: 11px;
  color: var(--tk-muted);
  text-align: center;
  padding-top: 4px;
  min-height: 14px;
}
/* Founder LIVE EDIT BLOCK 2026-04-30 (block 4 — unify Founder Admin):
   subtitle reads "Live platform controls" so the floating panel matches
   Account/chat surfaces; link-button is the visual primitive shared by
   Spin Wheel / Legal / Site Info / Platform Identity sections that
   bridge to the canonical /demo/account or /privacy routes. */
.tk-demo-admin-subtitle {
  display: block;
  font-size: 11px;
  color: var(--tk-muted);
  margin: -2px 0 8px;
  letter-spacing: .02em;
}
.tk-demo-admin-link-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 8px 12px;
  border-radius: 8px;
  border: 1px solid var(--tk-line);
  background: var(--tk-paper, #fff);
  color: var(--tk-leaf-deep);
  font-size: 12px;
  font-weight: 700;
  text-decoration: none;
  transition: background .15s, transform .12s;
}
.tk-demo-admin-link-button:hover {
  background: var(--tk-leaf-soft);
  transform: translateY(-1px);
}
.tiktoke-admin-group-header {
  font-size: 10px;
  font-weight: 800;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--tk-muted);
  margin: 12px 4px 6px;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--tk-line);
}
.tiktoke-admin-group-header:first-child { margin-top: 0; }
.tk-demo-admin-field {
  display: grid;
  gap: 4px;
  min-width: 0;
  max-width: 100%;
  box-sizing: border-box;
}
.tk-demo-admin-field span {
  color: var(--tk-muted);
  font-size: 10px;
  font-weight: 900;
  letter-spacing: .04em;
  text-transform: uppercase;
  /* Founder LIVE EDIT 2026-04-30 (founder admin text fit): field labels
     like "Move desktop menu vertically (px, step 3)" exceed the 270px
     panel width — wrap them so the full label is always visible. */
  white-space: normal;
  word-break: break-word;
  overflow-wrap: anywhere;
  line-height: 1.35;
}
/* Founder LIVE EDIT 2026-04-30 (founder admin minimize-whole-panel +
   text-fit pass): the founder asked for two things — text inside the
   panel must not get cut off, and the entire panel must minimize at
   will (not just per-section accordions). The new title row holds a
   minimize toggle button that hides .tk-demo-admin-body and shrinks
   the panel to the title bar only. State is persisted under
   localStorage[tk-founder-admin-panel-minimized-v1] so reload and
   page navigation remember the founder's preference. When minimized,
   the panel becomes a compact pill-style bar that can be reopened
   with one click. */
/* Founder LIVE EDIT 2026-05-01 RE-RUN PASS — floating Founder Admin
   collapsed-state overlap fix + expanded-state polish. Founder:
   "Collapsed state text overlaps" + "Expanded state still looks
   like dumped controls". Surgical changes:
     • align-items center (was flex-start) so title + minimize
       button line up cleanly on the same baseline
     • gap 12px (was 8px) so button does not crowd the title text
     • title gets padding-right + min-height so the rendered box
       reserves space for both elements without wrap collision
     • collapsed pill rounds to 999px and tightens padding
     • section cards get hairline borders + subtle bg so they
       look like grouped controls instead of dumped form rows
   The minimize button itself is unchanged (26x26 pill). */
.tk-demo-admin-titlebar {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 8px;
}
.tk-demo-admin-titlebar-text {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding-right: 4px;
}
.tk-demo-admin-title {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.tk-demo-admin-minimize {
  flex-shrink: 0;
  width: 26px;
  height: 26px;
  min-height: 26px;
  padding: 0;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 16%, transparent);
  background: color-mix(in srgb, var(--tk-paper) 80%, transparent);
  color: var(--tk-leaf-deep);
  font-weight: 800;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background .12s, transform .12s;
}
.tk-demo-admin-minimize:hover {
  background: var(--tk-leaf-soft);
  transform: translateY(-1px);
}
/* Founder LIVE EDIT 2026-05-01 (FLOATING ADMIN BUTTON REDESIGN —
   collapsed pill): Founder: "current collapsed floating admin
   button looks like a rough placeholder. Mobile collapsed button
   height must be about HALF current height. compact premium
   pill/card. clear 'Founder Admin' label. no overlapping text. no
   huge empty vertical height. no raw plus in oversized white box.
   visually consistent with TikToke rounded green/cream theme."
   The collapsed pill is now a compact rounded leaf-deep capsule
   with cream text + cream "+" expand glyph; mobile shrinks the
   vertical padding to 4px (was 6px) so the collapsed height drops
   to roughly half the prior value. The titlebar layout keeps the
   label and the toggle button on the same baseline. */
.tk-demo-admin-menu[data-tk-panel-minimized="true"] {
  width: auto;
  min-width: 0;
  max-width: 220px;
  max-height: none;
  padding: 4px 6px 4px 14px;
  border-radius: 999px;
  overflow: visible;
  background: var(--tk-leaf-deep, var(--tk-leaf-deep, #1f3d2c));
  border-color: var(--tk-leaf-deep, var(--tk-leaf-deep, #1f3d2c));
  box-shadow:
    0 4px 14px rgba(20, 20, 18, 0.18),
    inset 0 1px 0 rgba(255, 255, 255, 0.08);
}
.tk-demo-admin-menu[data-tk-panel-minimized="true"] .tk-demo-admin-body {
  display: none;
}
.tk-demo-admin-menu[data-tk-panel-minimized="true"] .tk-demo-admin-titlebar {
  margin-bottom: 0;
  gap: 8px;
  padding: 0;
  border-bottom: 0;
  align-items: center;
}
.tk-demo-admin-menu[data-tk-panel-minimized="true"] .tk-demo-admin-titlebar-text {
  padding-right: 0;
}
.tk-demo-admin-menu[data-tk-panel-minimized="true"] .tk-demo-admin-subtitle {
  display: none;
}
.tk-demo-admin-menu[data-tk-panel-minimized="true"] .tk-demo-admin-title {
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .02em;
  color: #fffaf1;
  white-space: nowrap;
}
.tk-demo-admin-menu[data-tk-panel-minimized="true"] .tk-demo-admin-minimize {
  width: 24px;
  height: 24px;
  min-height: 24px;
  background: rgba(255, 255, 255, 0.14);
  border-color: rgba(255, 255, 255, 0.22);
  color: #fffaf1;
  font-size: 14px;
}
.tk-demo-admin-menu[data-tk-panel-minimized="true"] .tk-demo-admin-minimize:hover {
  background: rgba(255, 255, 255, 0.22);
}
@media (max-width: 720px) {
  /* Founder: "Mobile: collapsed button height must be about HALF
     current height." Tighter vertical padding + smaller minimize
     button drop the collapsed pill from ~38px to ~22px on mobile. */
  .tk-demo-admin-menu[data-tk-panel-minimized="true"] {
    padding: 2px 4px 2px 12px;
    max-width: 200px;
  }
  .tk-demo-admin-menu[data-tk-panel-minimized="true"] .tk-demo-admin-minimize {
    width: 20px;
    height: 20px;
    min-height: 20px;
    font-size: 13px;
  }
  .tk-demo-admin-menu[data-tk-panel-minimized="true"] .tk-demo-admin-title {
    font-size: 11px;
  }
}
/* Expanded sections — give them card-like grouping so the panel
   doesn't read as a wall of raw form rows. */
.tk-demo-admin-menu .tk-demo-admin-section {
  background: color-mix(in srgb, var(--tk-paper) 70%, transparent);
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 10%, transparent);
  border-radius: 10px;
  padding: 6px 10px;
  margin-bottom: 8px;
}
.tk-demo-admin-menu .tk-demo-admin-section[open] {
  background: #ffffff;
  border-color: color-mix(in srgb, var(--tk-leaf-deep) 16%, transparent);
  box-shadow: 0 1px 2px color-mix(in srgb, var(--tk-leaf-deep) 6%, transparent);
}
.tk-demo-admin-menu .tk-demo-admin-summary {
  cursor: pointer;
  font-weight: 700;
  font-size: 13px;
  color: var(--tk-leaf-deep, var(--tk-leaf-deep, #1f3d2c));
  padding: 4px 0;
  list-style: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.tk-demo-admin-menu .tk-demo-admin-summary::after {
  content: "▾";
  font-size: 10px;
  opacity: 0.5;
  transition: transform .15s;
}
.tk-demo-admin-menu .tk-demo-admin-section[open] > .tk-demo-admin-summary::after {
  transform: rotate(180deg);
}
.tk-demo-admin-menu .tk-demo-admin-section-body {
  padding: 6px 0 4px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.tk-demo-admin-actions {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px;
  min-width: 0;
}
/* Founder zero-blocker visual repair 2026-04-30: Apply-for-everyone must surface
   Saving/Applied/Failed status without alert popups so Founder can see the
   button worked. Stays inside the panel, contained width, and respects the
   panel typography. */
.tk-demo-admin-status {
  display: block;
  width: 100%;
  max-width: 100%;
  min-width: 0;
  box-sizing: border-box;
  margin: 4px 0 0;
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .02em;
  color: var(--tk-leaf-deep);
  white-space: normal;
  word-break: break-word;
}
.tk-demo-admin-status:empty {
  display: none;
}
.tk-demo-admin-actions button:last-child {
  background: var(--tk-leaf-deep);
  color: var(--tk-paper);
}
.tk-demo-admin-menu span {
  color: var(--tk-muted);
  font-size: 11px;
  font-weight: 800;
}
.tk-homepage-insert-control {
  position: relative;
  width: var(--tk-content-width);
  margin: -10px auto 2px;
  display: grid;
  place-items: center;
  z-index: 2;
}
.tk-homepage-insert-plus {
  width: 28px;
  height: 28px;
  border-radius: 999px;
  border: 1px dashed color-mix(in srgb, var(--tk-leaf-deep) 28%, transparent);
  background: color-mix(in srgb, var(--tk-paper) 90%, transparent);
  color: var(--tk-leaf-deep);
  font: inherit;
  font-size: 18px;
  font-weight: 950;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 10px 24px color-mix(in srgb, var(--tk-leaf-deep) 8%, transparent);
}
.tk-homepage-insert-menu {
  position: absolute;
  top: 34px;
  display: grid;
  gap: 8px;
  width: min(310px, calc(100vw - 32px));
  padding: 10px;
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 16%, transparent);
  border-radius: 16px;
  background: color-mix(in srgb, var(--tk-paper) 97%, transparent);
  box-shadow: 0 18px 42px rgba(20,20,18,.18);
}
.tk-homepage-insert-menu[hidden] { display: none !important; }
.tk-homepage-insert-tabs {
  display: flex;
  gap: 6px;
}
.tk-homepage-insert-tabs button,
.tk-homepage-insert-menu select,
.tk-homepage-insert-menu [data-tk-homepage-insert-apply] {
  min-width: 0;
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 14%, transparent);
  border-radius: 999px;
  padding: 8px 10px;
  background: var(--tk-paper);
  color: var(--tk-leaf-deep);
  font: inherit;
  font-size: 12px;
  font-weight: 900;
}
.tk-homepage-insert-menu [data-tk-homepage-insert-apply] {
  background: var(--tk-leaf-deep);
  color: var(--tk-paper);
}
.tk-homepage-insert-menu small {
  min-height: 14px;
  color: var(--tk-muted);
  font-size: 11px;
}

.tk-receipt-list {
  display: grid;
  gap: 8px;
  max-width: 620px;
  width: 100%;
  margin: 0 auto;
}
.tk-receipt-list div {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding: 10px 0;
  border-bottom: 1px solid var(--tk-line);
}
.tk-receipt-total {
  font-weight: 900;
  color: var(--tk-leaf-deep);
}

/* =============== PLAY HEADER + IFRAME ===============
   Single header inside the order section, no second card. Only the iframe
   below reads as a box. */
.tk-play-head {
  display: grid; gap: 5px;
  justify-items: center;
  text-align: center;
  max-width: 720px;
  margin: 0 auto;
  background: transparent;
  border: 0;
  padding: 0;
  order: var(--tk-order-desktop-play-head-order, 5);
}
.tk-play-label {
  margin: 0; font-size: 11px; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--tk-leaf); font-weight: 700;
}
.tk-play-title {
  margin: 2px 0 0;
  font-size: clamp(22px, 3.6vw, 30px);
  line-height: 1.18; font-weight: 800;
  color: var(--tk-ink);
}
.tk-play-subtitle {
  margin: 4px 0 0;
  font-size: 15px; color: var(--tk-ink-soft); font-weight: 600;
}
.tk-play-tagline {
  margin: 2px 0 0; color: var(--tk-muted); font-size: 13px;
}

.tk-play-frame {
  position: relative;
  width: var(--tk-play-frame-desktop-max-width, 100%);
  max-width: var(--tk-play-frame-desktop-max-width, 100%);
  aspect-ratio: 16 / 9;
  min-height: 360px;
  margin-top: var(--tk-play-fade-top-height);
  margin-bottom: 0;
  margin-left: auto;
  margin-right: auto;
  box-sizing: border-box;
  background: #0a0d11;
  border: 0;
  outline: 0;
  border-radius: 0;
  overflow: visible;
  box-shadow: none;
  order: var(--tk-order-desktop-play-frame-order, 6);
}
/* Founder zero-blocker visual repair 2026-04-30: when demo_play.embedFrame.align
   is "center" the desktop game frame must mirror left/right gutters; this is
   the explicit JSON-fed alignment hook so future align modes (start/end) can
   be added without re-engineering the layout. Body attribute is set by
   demo.js applyDemoPlayConfig(). */
body[data-tk-play-frame-align="center"] .tk-play-frame {
  margin-left: auto !important;
  margin-right: auto !important;
}
.tk-play-frame::before,
.tk-play-frame::after {
  content: none;
}
.fade-mask-top,
.fade-mask-bottom {
  position: absolute;
  left: 0;
  width: 100%;
  pointer-events: none;
  z-index: 3;
}
.fade-mask-top {
  top: 0;
  height: var(--tk-play-fade-top-height);
  /* Founder Pass 10.6.x 2026-05-04 — founder rule (verbatim):
     "you removed the fade above my game when its embedded on the
     home page!!! fix that, it faded into the page BG color !".
     Earlier today the menu surface was repointed to --tk-bg, which
     made the previous gradient (--page-bg-color → game-edge) fade
     INVISIBLE because --page-bg-color = --tk-bg = the page itself.
     Pin the top of the gradient to a perceptible dark cap derived
     from --tk-play-game-edge-color, then fade INTO --tk-bg/--page-bg
     so the fade still resolves into the page bg color the founder
     asked for. Result: a soft dark cap above the iframe blending
     into the homepage neutral grey, regardless of brand theme. */
  background: linear-gradient(to bottom,
    color-mix(in srgb, var(--tk-play-game-edge-color) 56%, transparent) 0%,
    color-mix(in srgb, var(--tk-play-game-edge-color) 36%, transparent) 38%,
    color-mix(in srgb, var(--page-bg-color) 22%, transparent) 78%,
    transparent 100%);
  mask-image: linear-gradient(to bottom, #000 0%, rgba(0,0,0,0.92) 48%, rgba(0,0,0,0.32) 84%, transparent 100%);
}
.fade-mask-bottom {
  display: none;
  bottom: 0;
  height: 0;
  background: none;
}
/* Founder hotfix 2026-04-28: these masks are outside the iframe, not over the
   game. Do not move them inside; faded HUD/buttons were the broken behavior. */
.tk-frame-fade-top {
  top: calc(-1 * var(--tk-play-fade-top-height));
}
.tk-frame-fade-bottom {
  display: none;
  bottom: 0;
}
.tk-fullscreen-arrow {
  position: absolute;
  top: -48px;
  right: auto;
  left: var(--tk-fullscreen-arrow-left, auto);
  z-index: 4;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 42px;
  color: var(--tk-leaf);
  font-size: 34px;
  font-weight: 900;
  line-height: 1;
  pointer-events: none;
  text-shadow:
    0 0 12px color-mix(in srgb, var(--tk-leaf) 78%, transparent),
    0 2px 0 rgba(255, 255, 255, 0.85);
  animation: tkFullscreenArrowDown 0.72s ease-in-out infinite;
  animation-iteration-count: infinite;
}
.tk-fullscreen-arrow:not([data-aligned="true"]) {
  left: auto;
  right: 10px;
}
body[data-tk-performance="slow"] .tk-fullscreen-arrow {
  animation-duration: 0.72s !important;
  animation-iteration-count: infinite !important;
}
@keyframes tkFullscreenArrowDown {
  0%, 100% { transform: translateY(-8px) scale(1); opacity: 0.78; }
  50% { transform: translateY(0) scale(1.12); opacity: 1; }
}
.tk-play-frame iframe {
  position: relative; z-index: 1;
  width: 100%; height: 100%; border: 0; display: block;
  border-radius: inherit;
}
html.tk-play-frame-fullscreen-active,
body.tk-play-frame-fullscreen-active {
  overflow: hidden;
  overscroll-behavior: none;
  touch-action: none;
}
.tk-play-frame.tk-play-frame-fullscreen {
  position: fixed;
  inset: 0;
  z-index: 99999;
  width: 100vw;
  max-width: none;
  height: 100dvh;
  min-height: 100svh;
  margin: 0;
  aspect-ratio: auto;
  border-radius: 0;
  overflow: hidden;
  background: var(--tk-play-game-edge-color);
}
.tk-play-frame.tk-play-frame-fullscreen iframe {
  width: 100vw;
  height: 100dvh;
  border-radius: 0;
}
.tk-play-frame.tk-play-frame-fullscreen .tk-fullscreen-arrow,
.tk-play-frame.tk-play-frame-fullscreen .tk-frame-fade-top,
.tk-play-frame.tk-play-frame-fullscreen .tk-frame-fade-bottom {
  display: none;
}

@media (max-width: 720px) {
  .tk-account-shell {
    width: min(100%, var(--tk-account-shell-max-width-mobile, 100%));
    max-width: var(--tk-account-shell-max-width-mobile, 100%);
    margin-inline: auto;
  }
  .tk-main {
    max-width: 100vw;
    overflow-x: hidden;
  }
  .tk-order,
  .tk-play-frame {
    min-width: 0;
  }
	  .tk-play-frame {
	    width: var(--tk-play-frame-mobile-width);
	    max-width: var(--tk-play-frame-mobile-width);
	    min-height: var(--tk-play-frame-mobile-min-height-home);
	    margin-left: calc(50% - var(--tk-play-frame-mobile-half-width));
    margin-right: calc(50% - var(--tk-play-frame-mobile-half-width));
    border-radius: 0 0 var(--tk-play-frame-mobile-bottom-radius) var(--tk-play-frame-mobile-bottom-radius);
    overflow: visible;
    border: 0;
    outline: 0;
    box-shadow: none;
  }
	  .tk-play-frame iframe {
	    border-radius: 0 0 var(--tk-play-frame-mobile-bottom-radius) var(--tk-play-frame-mobile-bottom-radius);
	  }
	  body.tk-order-page .tk-play-frame {
	    min-height: var(--tk-play-frame-mobile-min-height-order);
	  }
  .tk-fullscreen-arrow {
    right: auto;
    top: -46px;
  }
  .tk-fullscreen-arrow:not([data-aligned="true"]) {
    right: 12px;
  }
  .tk-order-progress-step { font-size: 9px; }
  .tk-order-progress-label { letter-spacing: -0.02em; }
  .tk-play-head { text-align: center; }
  .tk-order-strip {
    display: contents;
  }
  .tk-order-strip-main {
    order: var(--tk-order-mobile-main-order, 1);
    text-align: center;
    width: 100%;
    justify-self: center;
  }
  .tk-order-map {
    order: var(--tk-order-mobile-map-order, 3);
    min-height: var(--tk-platform-map-active-order-height-mobile);
  }
  body.tk-order-page .tk-order-map {
    min-height: var(--tk-platform-map-order-height-mobile);
  }
  .tk-order-progress {
    order: var(--tk-order-mobile-progress-order, 4);
  }
  .tk-order-meta {
    order: var(--tk-order-mobile-meta-order, 5);
    justify-content: center;
  }
  .tk-order-strip-aside {
    order: var(--tk-order-mobile-view-order, 2);
    justify-self: center;
    align-self: center;
    justify-content: center;
    width: 100%;
  }
  .tk-play-head { order: var(--tk-order-mobile-play-head-order, 6); }
  .tk-play-frame { order: var(--tk-order-mobile-play-frame-order, 7); }
  .tk-order-points {
    justify-self: center;
    padding: var(--tk-win-pill-mobile-padding, var(--tk-win-pill-padding, 6px 14px));
  }
  .tk-order-points-value {
    font-size: var(--tk-win-pill-mobile-value-size, var(--tk-win-pill-value-size, 13px));
  }
}

.tk-access-lock {
  background:
    radial-gradient(circle at 50% 20%, color-mix(in srgb, var(--tk-leaf) 22%, transparent), transparent 44%),
    rgba(9, 12, 16, 0.72);
  color: var(--tk-paper);
}
.tk-access-panel {
  position: relative;
  padding: 24px 20px 22px;
  border: 1px solid color-mix(in srgb, var(--tk-paper) 14%, transparent);
  border-radius: 22px;
  background: linear-gradient(180deg, rgba(20, 25, 31, 0.94), rgba(9, 12, 16, 0.94));
  box-shadow: 0 24px 70px rgba(0, 0, 0, 0.42);
}
.tk-access-close {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 34px;
  height: 34px;
  border: 1px solid color-mix(in srgb, var(--tk-paper) 20%, transparent);
  border-radius: 999px;
  background: rgba(255,255,255,0.1);
  color: var(--tk-paper);
  font: inherit;
  font-weight: 1000;
  cursor: pointer;
  touch-action: manipulation;
}

/* =============== ROWS (Netflix style) =============== */
.tk-row {
  --tk-row-card-basis-active: var(--tk-row-card-basis-desktop, 240px);
  display: grid;
  gap: 10px;
  width: var(--tk-content-width);
  margin-left: auto;
  margin-right: auto;
  overflow: visible;
}
.tk-row-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
  gap: 10px 16px;
  position: relative;
  z-index: 30;
}
.tk-row-actions {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  gap: 8px;
}
.tk-row-title-wrap { display: grid; gap: 3px; }
.tk-row-head h2 {
  margin: 0;
  font-size: var(--tk-row-title-size);
  line-height: 1.05;
  color: var(--tk-row-title-color);
  letter-spacing: -0.03em;
}
.tk-row-sub {
  color: var(--tk-ink-soft);
  font-size: var(--tk-row-description-size);
  line-height: 1.25;
  max-width: 58ch;
}
.tk-row-track {
  display: flex;
  align-items: stretch;
  grid-auto-columns: minmax(0, var(--tk-row-card-basis-active, var(--tk-row-card-basis-desktop, 240px)));
  gap: var(--tk-row-track-gap, 12px);
  overflow-x: auto;
  /* Founder HARD CORRECTION 2026-05-03 — extra padding-block buys
     headroom so the float animation has room to breathe inside the
     scroll container without bumping the row above. */
  padding-block: 14px 24px;
  scrollbar-width: thin;
  background: transparent;
  position: relative;
  z-index: 1;
}
.tk-row-track::-webkit-scrollbar { height: 8px; }
.tk-row-track::-webkit-scrollbar-thumb { background: var(--tk-line-strong); border-radius: 999px; }
.tk-priority-signup-panel {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: 14px;
  align-items: center;
  padding: clamp(16px, 2.4vw, 26px);
  border: 1px solid color-mix(in srgb, var(--tk-leaf) 18%, transparent);
  border-radius: 26px;
  background:
    radial-gradient(circle at 8% 20%, color-mix(in srgb, var(--tk-warm) 18%, transparent), transparent 28%),
    linear-gradient(135deg, color-mix(in srgb, var(--tk-leaf-deep) 94%, transparent), color-mix(in srgb, var(--tk-leaf) 82%, transparent));
  color: var(--tk-paper);
  box-shadow: 0 24px 58px color-mix(in srgb, var(--tk-leaf-deep) 22%, transparent);
}
.tk-priority-signup-panel[data-animation="soft-bounce"] {
  animation: tkCardMediaFloat var(--tk-card-media-float-duration, 2880ms) ease-in-out infinite;
}
body[data-tk-animations="off"] .tk-priority-signup-panel {
  animation: none !important;
}
@media (prefers-reduced-motion: reduce) {
  .tk-priority-signup-panel {
    animation: none !important;
  }
}
.tk-priority-signup-orb {
  width: 54px;
  height: 54px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: var(--tk-warm);
  color: var(--tk-leaf-deep);
  font-size: 28px;
  font-weight: 1000;
  box-shadow: 0 0 28px color-mix(in srgb, var(--tk-warm) 36%, transparent);
}
.tk-priority-signup-copy {
  display: grid;
  gap: 4px;
}
.tk-priority-signup-copy strong {
  font-size: clamp(22px, 3vw, 34px);
  line-height: 1;
}
.tk-priority-signup-copy span,
.tk-priority-signup-copy em {
  color: rgba(255,255,255,0.82);
  font-style: normal;
}
.tk-priority-signup-actions {
  display: inline-flex;
  gap: 8px;
}
.tk-priority-signup-actions button {
  border: 0;
  border-radius: 999px;
  padding: 10px 15px;
  background: var(--tk-paper);
  color: var(--tk-leaf-deep);
  font: inherit;
  font-weight: 950;
  cursor: pointer;
}
.tk-priority-signup-actions button + button {
  /* Founder HARD CORRECTION 2026-05-04 — founder rule (verbatim):
     "on the 'build your toke profile' on mobile, use regular theme
     profile colors for the 'Log In' text, instead of light grey".
     Was rgba(255,255,255,0.16) bg + var(--tk-paper) text which
     read as light grey on the dark gradient panel. Now uses a soft
     brand pill (--tk-leaf-soft) with brand-primary text (--tk-leaf)
     so the 'Log In' label is in regular theme profile colour on
     every brand (TikToke green, Netbics soft red). */
  background: var(--tk-leaf-soft);
  color: var(--tk-leaf);
}
@keyframes tkPrioritySignupFloat {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-5px); }
}

/* Row card — populated by demo.js with SVG art only */
.tk-card {
  width: 100%;
  inline-size: var(--tk-row-card-basis-active, var(--tk-row-card-basis-desktop, 100%));
  flex: 0 0 var(--tk-row-card-basis-active, var(--tk-row-card-basis-desktop, 100%));
  background: transparent;
  border: 0;
  border-radius: var(--tk-card-radius);
  overflow: visible; cursor: pointer;
  transition: transform .15s ease, box-shadow .15s ease, border-color .15s, filter .15s;
  display: grid; grid-template-rows: auto auto;
  justify-items: center;
  justify-self: stretch;
  min-width: 0;
  align-content: start;
  box-shadow: none;
  padding-bottom: 2px;
}
.tk-card:hover { transform: translateY(-3px); filter: saturate(1.04); }
.tk-card[data-ai-sparkle="true"] .tk-card-art::before,
.tk-card[data-ai-sparkle="true"] .tk-card-art::after {
  content: "";
  position: absolute;
  z-index: 2;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: color-mix(in srgb, var(--tk-warm) 90%, transparent);
  box-shadow:
    18px 22px 0 color-mix(in srgb, var(--tk-leaf) 52%, transparent),
    48px 12px 0 color-mix(in srgb, var(--tk-warm) 42%, transparent),
    82px 54px 0 color-mix(in srgb, var(--tk-leaf) 36%, transparent);
  opacity: 0.72;
  animation: tkAiSparkle 2.8s ease-in-out infinite;
}
.tk-card[data-ai-sparkle="true"] .tk-card-art::before { left: 18px; top: 20px; }
.tk-card[data-ai-sparkle="true"] .tk-card-art::after {
  right: 26px;
  bottom: 28px;
  animation-delay: 1.1s;
}
@keyframes tkAiSparkle {
  0%, 100% { transform: translateY(0) scale(0.82); opacity: 0.32; }
  50% { transform: translateY(-4px) scale(1); opacity: 0.78; }
}
@media (prefers-reduced-motion: reduce) {
  .tk-card[data-ai-sparkle="true"] .tk-card-art::before,
  .tk-card[data-ai-sparkle="true"] .tk-card-art::after {
    animation: none;
  }
}
.tk-card-art {
  aspect-ratio: var(--tk-card-media-aspect-ratio, 1 / 1); width: 100%;
  /* Founder HARD CORRECTION 2026-05-03 — NO overlay behind product
     cards. Founder rule (verbatim): "I CAN STILL SEE AN OVERLAY
     BEHIND THE PRODUCTS ON THE HOMEPAGE. I SAID NO OVERLAY !!!
     FROM TEXT TO BACKGROUND FFS". Removed the cream/white radial
     + linear gradients AND the box-shadow that drew a frame
     behind each product tile. The SVG artwork inside still
     renders normally — it now sits directly on the page
     background, no colored frame, no shadow halo. */
  background: transparent;
  position: relative; overflow: visible;
  border-radius: var(--tk-card-media-radius, var(--tk-card-radius));
  box-shadow: none;
  transform: translateY(0);
  transition: transform .22s ease, box-shadow .22s ease;
  z-index: 50;
}
.tk-card:hover .tk-card-art {
  transform: translateY(calc(-1 * var(--tk-card-media-float-distance, 3px)));
}
/* Founder PASS 57 2026-05-02 (hanger physics, no random dance):
   The previous .tk-card-art animation looped tkCardMediaFloat
   continuously — Founder's complaint: "icons dance, but not like
   scrolling boxes on a hanger in real life. Stop random dancing."
   Idle dance is now off; cards only move when the carousel is being
   scrolled, via --hanger-swing-x / --hanger-swing-rot written by
   carousel-hanger-physics.js. transform-origin: top center makes
   the bottom of the card swing while the top stays anchored, like
   a box on a hanger. The fast-scroll override below is preserved
   for explicit "this row should snap quickly" Founder presets. */
.tk-card-art {
  transform-origin: top center;
  transform:
    translate3d(var(--hanger-swing-x, 0px), 0, 0)
    rotateZ(var(--hanger-swing-rot, 0deg));
  transition: transform 80ms linear;
  will-change: transform;
}
/* Founder PASS 57 2026-05-02 (square 4K Browse-by-category cards):
   1:1 image-backed cards, premium clean look, no gray pills. Source
   manifest at face/portal/cannabis/categories/category-graphics-manifest.json
   feeds .tk-category-card via demo.js (or future SPA layer). */
.tk-category-row {
  display: flex;
  gap: 12px;
  padding: 4px 16px;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  scrollbar-width: none;
}
.tk-category-row::-webkit-scrollbar { display: none; }
.tk-category-card {
  flex: 0 0 var(--tk-category-card-size, 168px);
  width:    var(--tk-category-card-size, 168px);
  aspect-ratio: 1 / 1;
  border-radius: 18px;
  overflow: hidden;
  position: relative;
  background:
    radial-gradient(circle at 50% 30%, color-mix(in srgb, var(--tk-leaf, var(--tk-leaf, #3a8f5a)) 22%, transparent), transparent 62%),
    linear-gradient(180deg, color-mix(in srgb, var(--tk-leaf-deep, var(--tk-leaf-deep, #1f3d2c)) 22%, transparent) 0%, color-mix(in srgb, var(--tk-leaf-deep, var(--tk-leaf-deep, #1f3d2c)) 38%, transparent) 100%),
    var(--tk-paper, #f7f5f0);
  border: 1px solid color-mix(in srgb, var(--tk-leaf, var(--tk-leaf, #3a8f5a)) 32%, transparent);
  box-shadow: 0 12px 28px color-mix(in srgb, var(--tk-leaf-deep, var(--tk-leaf-deep, #1f3d2c)) 12%, transparent);
  text-decoration: none;
  color: var(--tk-leaf-deep, var(--tk-leaf-deep, #1f3d2c));
  scroll-snap-align: start;
  cursor: pointer;
}
.tk-category-card-image {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Never load full 4K master into a small card. demo.js sets srcset
     so the browser picks 512/768/1024 sized variants. */
}
.tk-category-card-label {
  position: absolute;
  left: 12px;
  bottom: 10px;
  font-weight: 950;
  font-size: 14px;
  letter-spacing: 0.02em;
  color: var(--tk-paper, #f7f5f0);
  text-shadow: 0 2px 8px rgba(15, 39, 25, 0.45);
}
@media (max-width: 720px) {
  .tk-category-card { flex-basis: var(--tk-category-card-size-mobile, 132px); width: var(--tk-category-card-size-mobile, 132px); }
}
@media (min-width: 1180px) {
  .tk-category-card { flex-basis: var(--tk-category-card-size-desktop, 200px); width: var(--tk-category-card-size-desktop, 200px); }
}
body:not([data-tk-animations="off"])[data-tk-card-scroll-motion="legacy-idle-float"] .tk-card-art {
  /* legacy idle bounce kept behind a Founder opt-in flag for emergency rollback */
  animation: tkCardMediaFloat var(--tk-card-media-float-duration, 2880ms) ease-in-out infinite;
}
/* Founder HARD CORRECTION 2026-05-03 — homepage carousel float
   animation must run on desktop AND mobile by default. Founder
   reported the floating animation is not visible. Pre-fix: float
   was gated behind body[data-tk-card-scroll-motion="legacy-idle-float"]
   which is not set on default loads, so the float never ran. Fix:
   apply the float to every .tk-card-art whenever animations are
   enabled and reduced-motion is not preferred. Promo/ad cards
   (.tk-in-page-ad-card) already had this rule. Both paths respect
   data-tk-animations="off" and prefers-reduced-motion. */
body:not([data-tk-animations="off"]) .tk-card-art {
  animation: tkCardMediaFloat var(--tk-card-media-float-duration, 2880ms) ease-in-out infinite;
}
body:not([data-tk-animations="off"])[data-tk-card-scroll-motion="fast"] .tk-card-art {
  animation-duration: var(--tk-card-media-fast-scroll-duration, 944ms);
}
@media (prefers-reduced-motion: reduce) {
  .tk-card-art { animation: none; }
}
@keyframes tkCardMediaFloat {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(calc(-0.5 * var(--tk-card-media-float-distance, 3px))); }
}
body[data-tk-animations="off"] .tk-card-art {
  animation: none;
}
/* Founder LIVE EDIT 2026-05-01 (pass 50 — JSON-driven promo bounce):
   non-product / non-store cards (categories like Edibles, Prerolls,
   Mobile Order, ads, signup CTAs) inherit the promo float distance
   from --tk-card-media-promo-float-distance, set by demo.js from
   homepage.json#homepage_rows.carousel.cardMedia.promoFloatDistance.
   The fallback (9.375px) reflects the canonical product 6.25px × 1.5
   relationship, with the 1.25 boost already baked into both numbers. */
.tk-card:not([data-card-type="product"]):not([data-card-type="store"]) {
  --tk-card-media-float-distance: var(--tk-card-media-promo-float-distance, 9.375px);
}
.tk-in-page-ad-card,
.tk-priority-signup-panel {
  --tk-card-media-float-distance: var(--tk-card-media-promo-float-distance, 9.375px);
}
body:not([data-tk-animations="off"]) .tk-in-page-ad-card {
  animation: tkCardMediaFloat var(--tk-card-media-float-duration, 2880ms) ease-in-out infinite;
}
body[data-tk-animations="off"] .tk-in-page-ad-card,
body[data-tk-animations="off"] .tk-priority-signup-panel {
  animation: none !important;
}
@media (prefers-reduced-motion: reduce) {
  .tk-in-page-ad-card,
  .tk-priority-signup-panel { animation: none !important; }
}
.tk-card-body {
  /* Founder correction 2026-05-01 (NO container behind image/panel): the
     text/details area now sits directly on the page background — no
     cream panel, no border, no box-shadow, no backdrop-filter blur,
     no mask-image. Only the image (.tk-card-art) and the bare text
     are visible. Layout-related properties (positioning, width,
     margin-top overlap with image, padding from --tk-card-body-shelf-padding)
     are preserved so the text still reads in the right place — the
     "container" visuals are what's stripped. */
  position: relative;
  z-index: var(--tk-card-body-z-index, 1);
  width: var(--tk-card-body-shelf-width, 96%);
  justify-self: center;
  margin-top: var(--tk-card-body-shelf-offset, -22px);
  border-radius: 0;
  border: 0;
  background: transparent;
  box-shadow: none;
  backdrop-filter: none;
  -webkit-mask-image: none;
          mask-image: none;
}
/* Image stays the visual hero — sits above the body panel.
   Founder HARD CORRECTION 2026-05-03: image must have HIGHEST z-index
   in carousel item; container removed (overflow:visible above) so the
   float animation never disappears behind anything. */
.tk-card-art {
  z-index: var(--tk-card-art-z-index, 50);
  overflow: visible;
}
/* Founder LIVE EDIT BLOCK 2026-04-30 (item 2 — 1:1 + 3D cards): when the
   active homepage card-media type is "3d", the card art rotates slowly
   in idle, gets a soft shadow underneath, and reacts to scroll velocity
   (the existing wireHomepageCardMotion path already feeds scroll-velocity
   floats; rotation is added here). The 2D PNG fallback path keeps the
   art static unless data-tk-card-media-rotate is also true. Animations
   off and prefers-reduced-motion both stop the rotation/float. */
body[data-tk-card-media-type="3d"] .tk-card-art,
body[data-tk-card-media-rotate="true"] .tk-card-art {
  transform-style: preserve-3d;
  perspective: 720px;
  filter: drop-shadow(0 18px 22px color-mix(in srgb, var(--tk-leaf-deep) 18%, transparent));
}
body[data-tk-card-media-type="3d"] .tk-card-art > *,
body[data-tk-card-media-rotate="true"] .tk-card-art > * {
  animation: tkCardArtIdleRotate var(--tk-card-art-rotate-duration, 14s) cubic-bezier(.45,.05,.55,.95) infinite;
  transform-origin: 50% 60%;
  will-change: transform;
}
@keyframes tkCardArtIdleRotate {
  0%   { transform: rotateY(-8deg) rotateX(2deg); }
  50%  { transform: rotateY(8deg)  rotateX(-2deg); }
  100% { transform: rotateY(-8deg) rotateX(2deg); }
}
body[data-tk-animations="off"][data-tk-card-media-rotate="true"] .tk-card-art > *,
body[data-tk-animations="off"][data-tk-card-media-type="3d"] .tk-card-art > * {
  animation: none !important;
  transform: none !important;
}
@media (prefers-reduced-motion: reduce) {
  body[data-tk-card-media-type="3d"] .tk-card-art > *,
  body[data-tk-card-media-rotate="true"] .tk-card-art > * {
    animation: none !important;
    transform: none !important;
  }
}
.tk-card-art svg,
.tk-card-art img,
.tk-card-art .tk-product-spin,
.tk-card-art .tk-product-media-asset {
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  /* Founder HARD CORRECTION 2026-05-03 — founder rule: "PRODUCT
     CAROUSEL ITEMS ARE NOT ROUNDED EDGES LIKE THE OTHERS!!! FIX IT".
     Product card images had radius 0; store card images had 10px
     (inherited via the store-specific override). Inheriting from
     .tk-card-art makes every carousel image (product, store, ad,
     category) round to the same --tk-card-media-radius the parent
     uses, so the corners match across the homepage. */
  border-radius: inherit;
}
.tk-card[data-card-type="product"] .tk-product-spin,
.tk-card[data-card-type="product"] .tk-product-media-asset {
  /* Founder live edit 2026-04-30 supersedes the older contained-thumbnail
     behavior: normal homepage product/logo/store media must fill a true 1:1
     square object with no inner rectangle or dead gap. */
  background: #fff;
  object-fit: cover;
}
.tk-card[data-card-type="store"] .tk-card-art {
  /* Founder live edit 2026-04-29: store/business media must fill the card
     media wrapper edge-to-edge in every Store Card Media Style. Product cards
     keep their separate crop rules; this store-only rule prevents the old
     pasted-square logo/card look from coming back.
     Founder HARD CORRECTION 2026-05-03 — overflow visible so the float
     animation never disappears behind a sibling/parent. The img/svg
     children still have border-radius: inherit and inset:0 so the
     visible artwork still hugs the rounded square boundary; only the
     bounding box stops clipping the float Y-translate. */
  padding: 0;
  overflow: visible;
  border-radius: var(--tk-card-media-radius, var(--tk-card-radius));
}
.tk-card[data-card-type="store"] .tk-card-art svg,
.tk-card[data-card-type="store"] .tk-card-art img,
.tk-card[data-card-type="store"] .tk-card-art canvas,
.tk-card[data-card-type="store"] .tk-card-art video,
.tk-card[data-card-type="store"] .tk-card-art .tk-store-media-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  min-width: 100%;
  min-height: 100%;
  display: block;
  object-fit: cover;
  border-radius: inherit;
}
body[data-tk-store-media-style="flag"] .tk-card[data-card-type="store"] .tk-card-art {
  overflow: hidden;
  perspective: 620px;
  background:
    radial-gradient(circle at 70% 22%, rgba(255,255,255,0.74), transparent 22%),
    linear-gradient(125deg, rgba(19, 53, 35, 0.96), rgba(82, 126, 68, 0.82) 52%, rgba(20, 42, 29, 0.94));
}
body[data-tk-store-media-style="flag"] .tk-card[data-card-type="store"] .tk-card-art::before {
  content: "";
  position: absolute;
  z-index: 3;
  left: 11%;
  top: 10%;
  width: 5px;
  height: 76%;
  border-radius: 999px;
  background: linear-gradient(180deg, #f6e2a7, #8b6a2b 48%, #f7e7b4);
  box-shadow: 12px 8px 26px rgba(8, 24, 15, 0.34);
}
body[data-tk-store-media-style="flag"] .tk-card[data-card-type="store"] .tk-card-art svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  transform-origin: 50% 50%;
  clip-path: none;
  filter: drop-shadow(0 18px 22px rgba(5, 20, 12, 0.28)) saturate(1.08);
  animation: tkLogoFlagWave 2.9s cubic-bezier(.45,.02,.2,1) infinite;
}
body[data-tk-store-media-style="flag"] .tk-store-logo,
body[data-tk-store-media-style="flag"] .tk-map-logo {
  transform-origin: 50% 50%;
  animation: tkLogoFlagBadgeWave 4.8s ease-in-out infinite;
}
body[data-tk-store-media-style="flag"] .tk-card[data-card-type="store"] .tk-card-art::after,
body[data-tk-store-media-style="flag"] .tk-store-logo::after,
body[data-tk-store-media-style="flag"] .tk-map-logo::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    repeating-linear-gradient(90deg, rgba(255,255,255,0.16) 0 5px, rgba(11,35,22,0.08) 5px 10px, transparent 10px 20px),
    linear-gradient(100deg, transparent 0%, rgba(255,255,255,0.24) 44%, transparent 68%);
  mix-blend-mode: screen;
  opacity: 0.72;
  animation: tkLogoFlagSheen 2.9s ease-in-out infinite;
}
@keyframes tkLogoFlagWave {
  0%, 100% { transform: perspective(620px) rotateY(-8deg) skewY(.4deg) translateX(-1px) scale(1.055, 1.035); }
  25% { transform: perspective(620px) rotateY(-3deg) skewY(-2.2deg) translateX(1px) scale(1.065, 1.04); }
  50% { transform: perspective(620px) rotateY(6deg) skewY(1.8deg) translateX(-1px) scale(1.055, 1.035); }
  75% { transform: perspective(620px) rotateY(-5deg) skewY(-1.4deg) translateX(1px) scale(1.07, 1.04); }
}
@keyframes tkLogoFlagBadgeWave {
  0%, 100% { transform: perspective(420px) rotateY(-4deg) skewY(.2deg); }
  50% { transform: perspective(420px) rotateY(5deg) skewY(-1.2deg); }
}
@keyframes tkLogoFlagSheen {
  0%, 100% { transform: translateX(-24%) skewX(-8deg); opacity: 0.34; }
  50% { transform: translateX(20%) skewX(10deg); opacity: 0.78; }
}
body[data-tk-store-media-style="float"] .tk-card[data-card-type="store"] .tk-card-art {
  border-radius: calc(var(--tk-card-radius) + 8px);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tk-leaf-deep) 10%, transparent);
}
body[data-tk-store-media-style="float"] .tk-card[data-card-type="store"] .tk-card-art svg {
  transform: perspective(460px) translateY(0) rotateX(1.2deg) rotateY(-2.5deg) scale(1.02);
  filter: drop-shadow(0 16px 22px color-mix(in srgb, var(--tk-leaf-deep) 20%, transparent));
  animation: tkLogoFloat 4.6s ease-in-out infinite;
}
body[data-tk-store-media-style="static"] .tk-card[data-card-type="store"] .tk-card-art svg,
body[data-tk-store-media-style="static"] .tk-store-logo,
body[data-tk-store-media-style="static"] .tk-map-logo {
  animation: none;
  transform: none;
}
@keyframes tkLogoFloat {
  0%, 100% { transform: perspective(460px) translateY(1px) rotateX(1.2deg) rotateY(-2.5deg) scale(1.02); }
  50% { transform: perspective(460px) translateY(-5px) rotateX(2.5deg) rotateY(2deg) scale(1.035); }
}
@media (prefers-reduced-motion: reduce) {
  body[data-tk-store-media-style="flag"] .tk-card[data-card-type="store"] .tk-card-art svg,
  body[data-tk-store-media-style="float"] .tk-card[data-card-type="store"] .tk-card-art svg,
  body[data-tk-store-media-style="flag"] .tk-store-logo,
  body[data-tk-store-media-style="flag"] .tk-map-logo,
  body[data-tk-store-media-style="flag"] .tk-card[data-card-type="store"] .tk-card-art::after,
  body[data-tk-store-media-style="flag"] .tk-store-logo::after,
  body[data-tk-store-media-style="flag"] .tk-map-logo::after {
    animation: none;
  }
}
.tk-card-badge {
  position: absolute; top: 10px; left: 10px;
  background: var(--tk-verified-green); border-radius: 999px; padding: 3px 9px;
  font-size: 11px; color: var(--tk-paper); font-weight: 700;
  letter-spacing: 0.04em;
}
.tk-in-page-ad-placement {
  --tk-ad-grid-columns-active: var(--tk-ad-grid-columns-desktop, repeat(auto-fit, minmax(230px, 1fr)));
  width: var(--tk-content-width);
  margin: 0 auto 8px;
}
.tk-homepage-inserted-content {
  --tk-ad-grid-columns-active: var(--tk-ad-grid-columns-desktop, repeat(auto-fit, minmax(230px, 1fr)));
  position: relative;
  width: var(--tk-content-width);
  margin: 0 auto 8px;
}
.tk-in-page-ad-grid {
  display: grid;
  grid-template-columns: var(--tk-ad-grid-columns-active, var(--tk-ad-grid-columns-desktop, repeat(auto-fit, minmax(230px, 1fr))));
  gap: 9px;
}
.tk-homepage-inserted-card-slot {
  position: relative;
  min-width: 0;
}
.tk-homepage-inserted-card-slot .tk-admin-card-controls {
  top: 8px;
  right: 8px;
}
.tk-in-page-ad-card {
  display: grid;
  grid-template-columns: 88px minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
  min-height: 92px;
  padding: 9px;
  border-radius: 14px;
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 12%, transparent);
  /* Founder Pass 10.6.x 2026-05-04 — founder rule (verbatim):
     "for the guides/learn ads, it uses non-theme color backgrounds
     stll. point those to theme colors acrosss the baord". The card
     gradient was hardcoded TikToke green / amber RGB triplets, so
     Netbics rendered green ad cards. Routed through --tk-warm /
     --tk-leaf-deep / --tk-leaf so each brand renders in its own
     theme: TikToke green-warm, Netbics red-warm. */
  background:
    radial-gradient(circle at 92% 18%, color-mix(in srgb, var(--tk-warm) 24%, transparent), transparent 26%),
    linear-gradient(135deg, color-mix(in srgb, var(--tk-leaf-deep) 96%, transparent), color-mix(in srgb, var(--tk-leaf) 92%, transparent));
  color: var(--tk-paper);
  text-decoration: none;
  box-shadow: 0 12px 28px color-mix(in srgb, var(--tk-leaf-deep) 12%, transparent);
  overflow: hidden;
}
.tk-in-page-ad-media {
  display: block;
  aspect-ratio: 1;
  border-radius: 11px;
  /* Founder Pass 10.6 final 2026-05-04 — founder rule (verbatim):
     "on netbics: for 'register your store', i see green colors in
     the image. use theme colors and point tiktokes to themecolrs,
     not hard coded". Was hardcoded green RGB stops; now color-mix
     on --tk-leaf / --tk-leaf-deep so each brand renders in its
     own theme — TikToke green, Netbics soft red — by inheritance. */
  background:
    radial-gradient(circle at 42% 35%, color-mix(in srgb, var(--tk-leaf) 32%, var(--tk-paper)), transparent 20%),
    radial-gradient(circle at 68% 68%, color-mix(in srgb, var(--tk-leaf) 60%, transparent), transparent 28%),
    linear-gradient(145deg, var(--tk-leaf-deep), color-mix(in srgb, var(--tk-leaf) 70%, var(--tk-leaf-deep)));
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.14), 0 8px 18px color-mix(in srgb, var(--tk-leaf-deep) 30%, transparent);
}
.tk-in-page-ad-card[data-ad-visual*="digital"] .tk-in-page-ad-media,
.tk-in-page-ad-card[data-ad-visual*="accessories"] .tk-in-page-ad-media {
  background:
    radial-gradient(circle at 38% 32%, color-mix(in srgb, var(--tk-leaf) 36%, var(--tk-paper)), transparent 18%),
    radial-gradient(circle at 62% 62%, color-mix(in srgb, var(--tk-warm) 55%, transparent), transparent 26%),
    linear-gradient(145deg, var(--tk-leaf-deep), color-mix(in srgb, var(--tk-leaf-deep) 82%, var(--tk-leaf)));
}
.tk-in-page-ad-copy {
  display: grid;
  gap: 4px;
  min-width: 0;
}
.tk-in-page-ad-copy small {
  color: color-mix(in srgb, var(--tk-paper) 70%, transparent);
  font-size: 10px;
  font-weight: 950;
  letter-spacing: .13em;
  text-transform: uppercase;
}
.tk-in-page-ad-copy strong {
  /* Founder HARD CORRECTION 2026-05-03 — strong headline color
     forced to light cream so it reads on the ad card's dark-green
     gradient background. Founder report: "on tiktoke light version,
     the 'digital items' add has DARK GREEN text on DARK GREEN
     background. make it light green text". The default inherited
     rgb(31, 61, 44) (leaf-deep) from the page anchor color, which
     was invisible on the dark gradient. */
  color: var(--tk-leaf-light, #cfe9d3);
  font-size: clamp(15px, 1.6vw, 19px);
}
.tk-in-page-ad-copy em {
  color: color-mix(in srgb, var(--tk-paper) 76%, transparent);
  font-size: 11px;
  font-style: normal;
}
.tk-in-page-ad-cta {
  border-radius: 999px;
  padding: 7px 9px;
  background: color-mix(in srgb, var(--tk-paper) 92%, transparent);
  color: var(--tk-leaf-deep);
  font-size: 11px;
  font-weight: 950;
  white-space: nowrap;
}
.tk-homepage-inserted-content[data-layout="wide"] .tk-in-page-ad-grid,
.tk-in-page-ad-placement[data-layout="wide"] .tk-in-page-ad-grid {
  grid-template-columns: 1fr;
}
.tk-homepage-inserted-content[data-layout="wide"] .tk-in-page-ad-card {
  min-height: 104px;
  grid-template-columns: 118px minmax(0, 1fr) auto;
  border-radius: 16px;
  /* Founder Pass 10.6.x 2026-05-04 — wide ad card variant joined
     to the same theme-token recolour as the standard variant; was
     hardcoded TikToke green/warm RGB. */
  background:
    radial-gradient(circle at 94% 10%, color-mix(in srgb, var(--tk-warm) 18%, transparent), transparent 24%),
    linear-gradient(135deg, color-mix(in srgb, var(--tk-leaf-deep) 94%, transparent), color-mix(in srgb, var(--tk-leaf) 88%, transparent));
}
.tk-section-marker {
  width: var(--tk-content-width);
  margin: 4px auto 0;
  display: grid;
  place-items: center;
  text-align: center;
}
.tk-section-marker-inner {
  position: relative;
  display: inline-grid;
  justify-items: center;
  gap: 4px;
  padding: 18px 34px 16px;
  isolation: isolate;
}
.tk-section-marker-inner > span {
  position: absolute;
  inset: 5px 0 -2px;
  z-index: -1;
  border-radius: 48% 52% 45% 55% / 52% 40% 60% 48%;
  background:
    radial-gradient(circle at 28% 58%, rgba(216,143,60,.38), transparent 32%),
    radial-gradient(circle at 70% 40%, color-mix(in srgb, var(--tk-leaf) 26%, transparent), transparent 34%),
    linear-gradient(90deg, color-mix(in srgb, var(--tk-leaf-deep) 8%, transparent), rgba(216,143,60,.16), color-mix(in srgb, var(--tk-leaf-deep) 6%, transparent));
  filter: blur(.2px);
  transform: rotate(-1.5deg) skewX(-5deg);
}
.tk-section-marker h2 {
  margin: 0;
  color: var(--tk-leaf-deep);
  font-size: clamp(28px, 5vw, 58px);
  line-height: .92;
  letter-spacing: -0.07em;
}
.tk-section-marker p {
  margin: 0;
  color: var(--tk-ink-soft);
  font-size: 12px;
  font-weight: 800;
}
.tk-admin-card-controls {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 35;
  display: inline-flex;
  align-items: flex-start;
  gap: 5px;
}
.tk-admin-card-button,
.tk-admin-column-menu button,
.tk-admin-slot-menu button,
.tk-admin-slot-menu select {
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 18%, transparent);
  background: color-mix(in srgb, var(--tk-paper) 94%, transparent);
  color: var(--tk-leaf-deep);
  font: inherit;
  font-size: 11px;
  font-weight: 950;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 8px 20px rgba(20,20,18,.12);
}
.tk-admin-card-button {
  width: 26px;
  height: 26px;
  border-radius: 9px;
  display: inline-grid;
  place-items: center;
}
.tk-admin-column-control {
  position: relative;
  display: inline-flex;
  z-index: 45;
}
.tk-admin-slot-control {
  position: absolute;
  left: 8px;
  top: 8px;
  z-index: 10;
  display: inline-flex;
}
.tk-admin-column-menu,
.tk-admin-slot-menu {
  position: absolute;
  top: 31px;
  right: 0;
  z-index: 70;
  min-width: 128px;
  display: grid;
  gap: 5px;
  padding: 8px;
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 18%, transparent);
  border-radius: 13px;
  background: color-mix(in srgb, var(--tk-paper) 98%, transparent);
  box-shadow: 0 16px 34px rgba(20,20,18,.18);
}
.tk-admin-slot-menu {
  left: 0;
  right: auto;
  min-width: 170px;
}
.tk-admin-column-menu[hidden],
.tk-admin-slot-menu[hidden] { display: none !important; }
.tk-admin-column-menu strong,
.tk-admin-slot-menu strong {
  color: var(--tk-muted);
  font-size: 10px;
  font-weight: 950;
  letter-spacing: .12em;
  text-transform: uppercase;
}
.tk-admin-column-menu button,
.tk-admin-slot-menu button,
.tk-admin-slot-menu select {
  width: 100%;
  min-height: 26px;
  border-radius: 999px;
  text-align: left;
  padding: 7px 9px;
  box-shadow: none;
}
.tk-admin-column-menu button[data-active="true"] {
  background: var(--tk-leaf-deep);
  color: var(--tk-paper);
}
.tk-admin-column-menu small,
.tk-admin-slot-menu small,
.tk-admin-card-status {
  color: var(--tk-muted);
  font-size: 10px;
}
.tk-admin-card-status:empty { display: none; }
.tk-homepage-empty-slot {
  min-height: 92px;
  display: grid;
  place-items: center;
  border: 1px dashed color-mix(in srgb, var(--tk-leaf-deep) 24%, transparent);
  border-radius: 14px;
  color: var(--tk-muted);
  background: rgba(255,255,255,.5);
  font-size: 12px;
  font-weight: 900;
}
.tk-card-rank {
  /* Founder missed-items pass 2026-04-30 (item 8): the #1/#2 store rank badge
     moves to the LEFT side of the store picture so it never overlaps the
     favorite heart in the top-right. The badge stays readable and uses theme
     ink/cream tokens; favorite remains in top-right. */
  position: absolute; top: 10px; left: 10px;
  background: var(--tk-ink); color: var(--tk-bg); border-radius: 999px;
  padding: 3px 9px; font-size: 11px; font-weight: 700;
  z-index: 3;
}
.tk-favorite-heart {
  /* Founder HARD CORRECTION 2026-05-03 — founder rule: "move the
     favorite button a bit closer to the top right of the image".
     Pulled inset from 10px → 4px so the heart visually hugs the
     image's top-right corner. z-index above .tk-card-art (50) so
     the heart stays clickable above the floating image. */
  position: absolute;
  top: 4px;
  right: 4px;
  z-index: 60;
  width: auto;
  height: auto;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--tk-leaf-deep);
  font-size: 22px;
  line-height: 1;
  text-shadow: 0 2px 10px rgba(255,255,255,0.82), 0 5px 12px color-mix(in srgb, var(--tk-leaf-deep) 18%, transparent);
}
.tk-favorite-heart[data-favorited="true"],
.tk-favorite-button[data-favorited="true"] {
  color: var(--tk-warm);
}
.tk-card-body { padding: var(--tk-card-body-shelf-padding, 12px 14px 14px); display: grid; gap: 4px; }
/* Founder HARD CORRECTION 2026-05-03 (rev 3) — founder iterated:
   "STORE NAMES ARE BLACK!!! MAKE STORE NAMES THEME". --tk-ink
   was rendering as var(--tk-ink) (near-black) on light, which the
   founder reads as "black". Switched the card title to --tk-leaf
   (brand primary "theme" color — green on tiktoke, blue on
   netbics). Store name UNDER products keeps --tk-leaf-deep (DARK
   theme) via .tk-card-meta-store. */
.tk-card-name { margin: 0; font-size: 15px; font-weight: 760; letter-spacing: -0.02em; color: var(--tk-leaf) !important; }
.tk-card-meta { margin: 0; font-size: 12px; color: var(--tk-muted); }
/* Founder HARD CORRECTION 2026-05-03 (rev 2) — founder iterated:
   "hide the city name, then use the city's font for the 'ETA' and
   the random facts (FAST LOCAL ETA, etc)". City line is hidden;
   ETA line + .tk-card-fact mirror the location-pill font (13px,
   font-weight 700). */
.tk-card-meta.tk-card-meta-stack { display: grid; gap: 1px; }
.tk-card-meta-city { display: none !important; }
/* Founder HARD CORRECTION 2026-05-03 (rev 4) — founder iterated:
   "FONT AND FONTSIZE AND FONTWEIGHT TOO!!!". Match the hidden
   .tk-card-meta-city exactly: 12px, color muted, font-family
   inherits from .tk-card-meta (the parent), no weight override
   (inherits regular). letter-spacing reset to default. */
.tk-card-meta-eta {
  color: var(--tk-muted);
  font-size: 12px;
  font-weight: inherit;
  font-family: inherit;
  letter-spacing: normal;
  line-height: 1.18;
}
.tk-card-row {
  /* Founder LIVE EDIT 2026-05-01 (pass 51 — stars + price + avg one line):
     justify center so a single price element (unverified store) centers
     by itself, AND a [stars][price] pair centers as a paired group. The
     internal gap supplies horizontal breathing room.
     Founder HARD CORRECTION 2026-05-03 — founder rule: "REDUCE THE
     DISTANCE ABOVE ALL STAR RATINGS". margin-top 6px → 1px. */
  margin-top: 1px;
  display: flex;
  justify-content: center;
  align-items: center;
  flex-wrap: nowrap;
  gap: 8px;
  font-size: 12px;
  white-space: nowrap;
}
/* Founder HARD CORRECTION 2026-05-03 (rev 3) — founder iterated:
   "change the price amount to using regular theme color, instead
   of light theme color". --tk-leaf-light → --tk-leaf (regular
   brand primary; tiktoke green / netbics blue). */
.tk-card-price { font-weight: 700; color: var(--tk-leaf); }
.tk-card-stars { color: var(--tk-card-metric-color); letter-spacing: 0.04em; }
.tk-card-stars-meter {
  display: inline-flex;
  align-items: center;
  gap: 1px;
  color: color-mix(in srgb, var(--tk-warm) 30%, transparent);
}
.tk-star {
  position: relative;
  display: inline-block;
  color: color-mix(in srgb, var(--tk-warm) 25%, transparent);
}
.tk-star::before {
  content: "★";
  position: absolute;
  inset: 0;
  width: var(--tk-star-fill, 0%);
  overflow: hidden;
  color: var(--tk-warm);
}
.tk-product-spin {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  pointer-events: none;
  overflow: hidden;
}
/* Founder HARD CORRECTION 2026-05-03 — founder rule: "the product
   carousels have grey around the edges on the inside. make sure
   its fully all white background". The ::before / ::after pseudo-
   elements drew a dark radial behind the image (rgba(6,16,12,0.94)
   blurred 3px) which produced a grey halo around the rendered
   image where the dark gradient bled past the image's silhouette.
   Disabled both pseudos on the carousel cards so the spin span is
   pure white edge-to-edge. The product DETAIL page may want a
   different treatment in the future, but the homepage carousels
   must read as flat white. */
.tk-product-spin::before,
.tk-product-spin::after {
  content: none;
}
.tk-product-media-asset {
  /* Founder HARD CORRECTION 2026-05-03 — founder rule: "the homepage
     product images dont take up the entire carousel square image
     container. make sure every product properly FITS in it". The
     prior 76% × 78% caps left dead padding around each image; now
     the IMG fills the 1:1 art box edge-to-edge with object-fit:
     cover. The product DETAIL view still uses the smaller centered
     contain layout via the data-context="detail" override below. */
  position: relative;
  z-index: 2;
  width: 100%;
  height: 100%;
  max-height: 100%;
  object-fit: cover;
  /* Founder HARD CORRECTION 2026-05-03 — drop-shadow removed.
     The 0 20px 32px rgba(0,0,0,0.34) blur produced a grey halo
     around the image inside the white card. Founder wants flat
     all-white bg. Float animation kept; shadow is what created
     the perceived grey ring. */
  filter: none;
  animation: tkProductAssetFloat 5.8s ease-in-out infinite;
}
.tk-product-viewer {
  position: absolute;
  inset: 0;
  display: block;
  overflow: hidden;
  cursor: grab;
  touch-action: none;
}
.tk-product-viewer:active { cursor: grabbing; }
.tk-product-viewer-canvas {
  display: block;
  width: 100%;
  height: 100%;
}
.tk-product-viewer .tk-product-media-glow {
  pointer-events: none;
}
.tk-product-spin[data-media-mode="2d"] .tk-product-media-asset {
  animation: none;
}
.tk-product-spin[data-context="detail"] .tk-product-media-asset {
  width: min(78%, 440px);
  max-height: 86%;
}
.tk-product-media-glow {
  /* Founder HARD CORRECTION 2026-05-03 — disabled. Was a 58% radial
     gradient blurred 11px sitting behind the image; founder wants
     fully white background, no glow ring. */
  display: none;
}
.tk-product-image-row {
  display: grid;
  gap: 8px;
}
.tk-product-image-row[data-source="client"] {
  padding: 14px;
  border-radius: 20px;
  background:
    radial-gradient(circle at 82% 18%, rgba(255,255,255,0.18), transparent 28%),
    linear-gradient(135deg, var(--tk-leaf-deep), #2f7f4d);
  color: var(--tk-paper);
}
.tk-product-image-row h3 {
  margin: 0;
  color: var(--tk-leaf-deep);
  font-size: 15px;
  letter-spacing: -0.02em;
}
.tk-product-image-row[data-source="client"] h3 {
  color: var(--tk-paper);
}
.tk-product-image-carousel {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(150px, 1fr);
  gap: 10px;
  overflow-x: auto;
  padding-bottom: 2px;
  scrollbar-color: var(--tk-leaf) color-mix(in srgb, var(--tk-leaf-deep) 8%, transparent);
}
.tk-product-image-chip {
  position: relative;
  min-height: 84px;
  display: grid;
  place-items: end start;
  padding: 12px;
  border-radius: 18px;
  background:
    radial-gradient(circle at 70% 28%, rgba(255,255,255,0.86), transparent 26%),
    linear-gradient(135deg, color-mix(in srgb, var(--tk-leaf-deep) 8%, transparent), color-mix(in srgb, var(--tk-leaf) 13%, transparent));
  color: var(--tk-ink);
  font-size: 13px;
  font-weight: 850;
  overflow: hidden;
}
/* Founder Pass 10.6 2026-05-03 — image-bearing chips render as
   iPhone-aspect thumbnails. Founder HARD CORRECTION 2026-05-04:
   "remove the 'customer image' tag from INSIDE the image, and put
   the store name under the image". The chip is now a 2-row grid:
   row 1 = thumbnail (the image), row 2 = store-name text. The old
   overlay caption pill is gone. */
.tk-product-image-chip[data-has-image="true"] {
  padding: 0;
  min-height: 220px;
  display: grid;
  grid-template-rows: 1fr auto;
  background: transparent;
  border: 0;
  overflow: visible;
}
.tk-product-image-thumb {
  position: relative;
  display: block;
  overflow: hidden;
  border-radius: 18px;
  background: var(--tk-paper);
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 10%, transparent);
  aspect-ratio: 4 / 5;
}
.tk-product-image-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* Store name UNDER the image (not overlaid). Theme-coloured, lowercase,
   ellipsised on overflow. */
.tk-product-image-chip[data-has-image="true"] .tk-product-image-store-name {
  display: block;
  padding: 8px 4px 0;
  color: var(--tk-leaf-deep);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: 0.01em;
  /* Founder Pass 10.6 final closure 2026-05-04 — founder rule
     (verbatim): "make customer images use stores name That are
     capitalized by first Letter and not all small letters". Was
     text-transform: lowercase which forced 'cedar & cloud cannabis'.
     Now no transform so the source-of-truth store name capitalization
     ('Cedar & Cloud Cannabis') reaches the chip caption as-is. */
  text-transform: none;
  text-align: center;
  text-decoration: none;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.tk-product-image-chip[data-has-image="true"] .tk-product-image-store-name:hover {
  text-decoration: underline;
}
.tk-product-image-chip > span {
  position: relative;
  z-index: 1;
}
.tk-product-image-store-tag {
  position: absolute;
  right: 8px;
  bottom: 8px;
  z-index: 2;
  max-width: calc(100% - 16px);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  border-radius: 999px;
  padding: 4px 8px;
  background: color-mix(in srgb, var(--tk-leaf-deep) 92%, transparent);
  color: var(--tk-paper);
  font-size: 10px;
  font-weight: 900;
  text-decoration: none;
  box-shadow: 0 8px 18px color-mix(in srgb, var(--tk-leaf-deep) 20%, transparent);
}
.tk-product-image-row[data-source="client"] .tk-product-image-chip {
  background:
    radial-gradient(circle at 70% 24%, rgba(255,255,255,0.26), transparent 26%),
    linear-gradient(135deg, rgba(255,255,255,0.14), rgba(255,255,255,0.07));
  color: var(--tk-paper);
  border: 1px solid rgba(255,255,255,0.14);
}
.tk-product-customer-instructions {
  display: grid;
  gap: 8px;
  padding: 14px;
  border-radius: 20px;
  background: color-mix(in srgb, var(--tk-leaf-deep) 6%, transparent);
  border: 1px dashed color-mix(in srgb, var(--tk-leaf-deep) 18%, transparent);
}
.tk-product-customer-instructions h3,
.tk-product-customer-instructions p {
  margin: 0;
}
.tk-product-customer-instructions h3 {
  color: var(--tk-leaf-deep);
  font-size: 15px;
}
.tk-product-customer-instructions p {
  color: var(--tk-ink-soft);
  font-size: 13px;
  line-height: 1.45;
}
.tk-product-customer-instructions div {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
}
.tk-product-customer-instructions span {
  border-radius: 999px;
  padding: 6px 9px;
  background: rgba(255,255,255,0.82);
  color: var(--tk-leaf-deep);
  font-size: 11px;
  font-weight: 850;
}
.tk-product-compact-buy-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.tk-product-purchase-row {
  display: grid;
  gap: 14px;
  margin-top: 4px;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
}
.tk-product-quantity,
.tk-product-size-picker {
  display: grid;
  gap: 8px;
}
.tk-product-quantity span,
.tk-product-size-picker > span {
  color: var(--tk-muted);
  font-size: 11px;
  font-weight: 900;
  letter-spacing: .16em;
  text-transform: uppercase;
}
.tk-product-quantity-stepper {
  display: inline-flex;
  width: max-content;
  align-items: center;
  gap: 6px;
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 14%, transparent);
  border-radius: 999px;
  padding: 4px;
  background: rgba(255,255,255,0.76);
}
.tk-product-quantity-stepper button {
  width: 34px;
  height: 34px;
  border: 0;
  border-radius: 999px;
  background: var(--tk-leaf-deep);
  color: var(--tk-paper);
  font: inherit;
  font-weight: 900;
  cursor: pointer;
}
.tk-product-quantity input {
  width: 58px;
  min-height: 42px;
  border: 0;
  border-radius: 999px;
  padding: 0 8px;
  background: transparent;
  color: var(--tk-leaf-deep);
  font: inherit;
  font-weight: 900;
  text-align: center;
}
.tk-product-size-picker > div {
  display: flex;
  flex-wrap: wrap;
  gap: 9px;
}
.tk-product-size-picker button {
  min-width: 78px;
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 14%, transparent);
  border-radius: 15px;
  padding: 10px 12px;
  background: rgba(255,255,255,0.76);
  color: var(--tk-ink);
  font: inherit;
  cursor: pointer;
  display: grid;
  gap: 2px;
}
.tk-product-size-picker button[data-active="true"] {
  background: var(--tk-product-size-selected-color, var(--tk-leaf));
  color: #fff;
  border-color: var(--tk-product-size-selected-color, var(--tk-leaf));
}
.tk-product-size-picker small {
  opacity: .78;
  font-weight: 700;
}
.tk-product-add-cart {
  width: 100%;
  min-height: 48px;
  border: 0;
  border-radius: 999px;
  background: linear-gradient(135deg, var(--tk-leaf), #74c986);
  color: #082413;
  font: inherit;
  font-weight: 950;
  letter-spacing: .02em;
  cursor: pointer;
  box-shadow: 0 14px 30px color-mix(in srgb, var(--tk-leaf-deep) 18%, transparent);
}
.tk-product-stat-lines {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  color: var(--tk-leaf-deep);
}
.tk-product-cannabinoids span {
  border-radius: 999px;
  padding: 7px 11px;
  background: color-mix(in srgb, var(--tk-leaf-deep) 8%, transparent);
  color: var(--tk-leaf-deep);
  font-size: 13px;
  font-weight: 950;
}
.tk-product-terpenes {
  color: var(--tk-ink-soft);
  font-size: 14px;
  font-weight: 750;
  line-height: 1.4;
}
.tk-product-description {
  display: grid;
  gap: 8px;
  max-width: 980px;
  margin-top: 4px;
}
.tk-product-description h2 {
  margin: 0;
  color: var(--tk-leaf-deep);
  font-size: clamp(18px, 2vw, 24px);
  letter-spacing: -0.04em;
}
.tk-product-description p {
  margin: 0;
  color: var(--tk-ink-soft);
  font-size: clamp(14px, 1.2vw, 16px);
  line-height: 1.56;
}
.tk-card-art[data-spin="paused"] .tk-product-media-asset,
body[data-tk-performance="slow"] .tk-product-media-asset {
  animation-play-state: paused;
}
@keyframes tkProductAssetFloat {
  0%, 100% { transform: translateY(0) scale(1); }
  50% { transform: translateY(-4px) scale(1.02); }
}

/* =============== TOKEBOT BUTTON =============== */
.tk-tokebot {
  position: fixed; right: 16px; bottom: 12px; z-index: 40;
  background: linear-gradient(140deg, #ffffff 0%, #f0eee5 100%);
  border: 1px solid var(--tk-leaf); color: var(--tk-leaf-deep);
  border-radius: 999px; padding: 8px 14px 8px 10px;
  display: inline-flex; align-items: center; gap: 10px;
  cursor: pointer;
  /* Founder live edit 2026-04-30 + LIVE EDIT BLOCK 2026-04-30 (TOKEBOT
     black overlay removal): box-shadow stays NONE everywhere. The
     ::before / ::after pseudo-elements are explicitly nulled so any
     future stylesheet that tries to drop a shadow strip BEHIND
     TOKEBOT (the visible "black overlay only pixels below TOKEBOT")
     can't render. The button's own fill stays visible; only the
     unwanted overlay strip is killed. */
  box-shadow: none;
  font: inherit; font-size: 13px;
  /* Founder LIVE EDIT BLOCK 2026-04-30 (item 6 — shared floating fade):
     uses --tk-floating-fade-out-ms by default (the fade-out timing).
     When data-visible='true' the rule below swaps to fadeIn timing so
     in/out feel different per Founder's spec. Legacy
     --tk-scroll-top-fade-ms remains as a fallback so older code paths
     don't regress. */
  transition: opacity var(--tk-floating-fade-out-ms, var(--tk-scroll-top-fade-ms, 320ms)) var(--tk-floating-fade-easing, ease), transform var(--tk-floating-fade-out-ms, var(--tk-scroll-top-fade-ms, 320ms)) var(--tk-floating-fade-easing, ease), box-shadow .15s;
}
.tk-tokebot[data-visible="true"] {
  transition: opacity var(--tk-floating-fade-in-ms, var(--tk-scroll-top-fade-ms, 220ms)) var(--tk-floating-fade-easing, ease), transform var(--tk-floating-fade-in-ms, var(--tk-scroll-top-fade-ms, 220ms)) var(--tk-floating-fade-easing, ease), box-shadow .15s;
}
.tk-tokebot::before,
.tk-tokebot::after {
  content: none !important;
  background: transparent !important;
  box-shadow: none !important;
  display: none !important;
}
.tk-tokebot[data-visible="false"] {
  opacity: 0;
  pointer-events: none;
  transform: translateY(8px) scale(0.96);
  box-shadow: none;
}
.tk-tokebot:hover { transform: translateY(-2px); box-shadow: none; }
.tk-tokebot-mark { width: 32px; height: 32px; }

/* Founder PASS 68 2026-05-02 (TokeBot preview popup) + PASS 69 2026-05-02
   (header-aware boundary + compact density). Opens when the floating
   launcher is clicked or any header search submit fires. Anchored
   below the menu/header (Founder: "make sure it doesnt go up higher
   than where the menu starts"). Theme-token driven for NetBics +
   TikToke. All sizing/offset/density via CSS variables so Founder can
   tune later without hunting through this rule. */
:root {
  --tokebot-menu-boundary-top: 0px;        /* set by JS from header.getBoundingClientRect().bottom */
  --tokebot-popup-safe-gap: 12px;
  --tokebot-popup-top: calc(var(--tokebot-menu-boundary-top) + var(--tokebot-popup-safe-gap));
  --tokebot-popup-side-padding: 18px;
  --tokebot-popup-bottom-padding: 18px;
  --tokebot-popup-max-width: 460px;
  --tokebot-popup-max-height: calc(100dvh - var(--tokebot-popup-top) - var(--tokebot-popup-bottom-padding));
  --tokebot-popup-font-size: 13.5px;
  --tokebot-popup-font-size-mobile: 13px;
  --tokebot-popup-meta-font-size: 11.5px;
  --tokebot-popup-line-height: 1.42;
  --tokebot-popup-status-size: 13.5px;
  --tokebot-popup-input-size: 13.5px;
  --tokebot-popup-ask-size: 12.5px;
}
.tk-tokebot-popup {
  position: fixed;
  inset: 0;
  z-index: 9100;
  display: none;
  align-items: flex-start;
  justify-content: center;
  background: color-mix(in srgb, var(--tk-leaf-deep, var(--tk-leaf-deep, #1f3d2c)) 30%, transparent);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  padding-top: var(--tokebot-popup-top);
  padding-right: var(--tokebot-popup-side-padding);
  padding-bottom: var(--tokebot-popup-bottom-padding);
  padding-left: var(--tokebot-popup-side-padding);
  box-sizing: border-box;
  opacity: 0;
  transition: opacity 220ms ease-out;
}
.tk-tokebot-popup[data-tk-tokebot-popup-open="true"] {
  display: flex;
  opacity: 1;
}
.tk-tokebot-popup-card {
  background: var(--tk-paper, #f7f5f0);
  border: 1px solid color-mix(in srgb, var(--tk-leaf, var(--tk-leaf, #3a8f5a)) 26%, transparent);
  border-radius: 22px;
  width: 100%;
  max-width: var(--tokebot-popup-max-width);
  height: auto;
  max-height: var(--tokebot-popup-max-height);
  box-shadow: 0 30px 80px color-mix(in srgb, var(--tk-leaf-deep, var(--tk-leaf-deep, #1f3d2c)) 32%, transparent);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  font-family: inherit;
  font-size: var(--tokebot-popup-font-size);
  line-height: var(--tokebot-popup-line-height);
  position: relative;
  transform: translateY(8px) scale(0.98);
  transition: transform 240ms cubic-bezier(.2, .8, .2, 1);
}
.tk-tokebot-popup[data-tk-tokebot-popup-open="true"] .tk-tokebot-popup-card {
  transform: translateY(0) scale(1);
}
.tk-tokebot-popup-hero {
  padding: 18px 18px 12px;
  display: grid;
  place-items: center;
  gap: 10px;
  background:
    radial-gradient(circle at 50% 30%, color-mix(in srgb, var(--tk-leaf, var(--tk-leaf, #3a8f5a)) 14%, transparent), transparent 64%),
    var(--tk-paper, #f7f5f0);
  border-bottom: 1px solid color-mix(in srgb, var(--tk-leaf, var(--tk-leaf, #3a8f5a)) 12%, transparent);
}
.tk-tokebot-popup-status {
  font-size: var(--tokebot-popup-status-size);
  font-weight: 800;
  color: var(--tk-leaf-deep, var(--tk-leaf-deep, #1f3d2c));
  letter-spacing: 0.04em;
  min-height: 1.2em;
  text-align: center;
}
.tk-tokebot-popup-status em {
  font-style: normal;
  color: color-mix(in srgb, var(--tk-leaf-deep, var(--tk-leaf-deep, #1f3d2c)) 64%, transparent);
  font-weight: 600;
  font-size: var(--tokebot-popup-meta-font-size);
  display: block;
  margin-top: 2px;
}
.tk-tokebot-popup-body {
  padding: 12px 16px 14px;
  display: grid;
  gap: 10px;
  overflow-y: auto;
}
.tk-tokebot-popup-input {
  width: 100%;
  box-sizing: border-box;
  padding: 10px 12px;
  border-radius: 10px;
  border: 1px solid color-mix(in srgb, var(--tk-leaf, var(--tk-leaf, #3a8f5a)) 30%, transparent);
  background: var(--tk-paper, #f7f5f0);
  color: var(--tk-ink, #11221b);
  font: inherit;
  font-size: var(--tokebot-popup-input-size);
  outline: none;
  transition: border-color 160ms ease;
}
.tk-tokebot-popup-input:focus {
  border-color: var(--tk-leaf, var(--tk-leaf, #3a8f5a));
}
.tk-tokebot-popup-actions {
  display: flex;
  gap: 8px;
  align-items: center;
  justify-content: flex-end;
}
.tk-tokebot-popup-ask {
  background: var(--tk-leaf-deep, var(--tk-leaf-deep, #1f3d2c));
  color: var(--tk-paper, #f7f5f0);
  border: 0;
  border-radius: 999px;
  padding: 8px 16px;
  font: inherit;
  font-weight: 800;
  font-size: var(--tokebot-popup-ask-size);
  letter-spacing: 0.04em;
  cursor: pointer;
  transition: transform 120ms ease, background 160ms ease;
}
.tk-tokebot-popup-ask:hover { transform: translateY(-1px); }
.tk-tokebot-popup-ask:disabled {
  opacity: 0.6;
  cursor: progress;
}
.tk-tokebot-popup-close {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 30px;
  height: 30px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--tk-leaf-deep, var(--tk-leaf-deep, #1f3d2c)) 8%, transparent);
  border: 0;
  color: var(--tk-leaf-deep, var(--tk-leaf-deep, #1f3d2c));
  font: inherit;
  font-size: 17px;
  line-height: 1;
  cursor: pointer;
  display: grid;
  place-items: center;
  transition: background 160ms ease;
}
.tk-tokebot-popup-close:hover {
  background: color-mix(in srgb, var(--tk-leaf-deep, var(--tk-leaf-deep, #1f3d2c)) 16%, transparent);
}
.tk-tokebot-popup-question {
  font-size: var(--tokebot-popup-meta-font-size);
  font-weight: 700;
  color: color-mix(in srgb, var(--tk-leaf-deep, var(--tk-leaf-deep, #1f3d2c)) 78%, transparent);
  letter-spacing: 0.02em;
  padding: 6px 10px;
  border-radius: 8px;
  background: color-mix(in srgb, var(--tk-leaf, var(--tk-leaf, #3a8f5a)) 8%, transparent);
}
.tk-tokebot-popup-answer {
  font-size: var(--tokebot-popup-font-size);
  line-height: var(--tokebot-popup-line-height);
  color: var(--tk-ink-soft, #3c4a3f);
  min-height: 2.4em;
  padding: 10px 12px;
  border-radius: 10px;
  background: color-mix(in srgb, var(--tk-leaf, var(--tk-leaf, #3a8f5a)) 6%, transparent);
}
.tk-tokebot-popup-answer[data-tk-tokebot-popup-answer-tone="error"] {
  background: color-mix(in srgb, var(--tk-warm, #d68f3c) 16%, transparent);
  color: var(--tk-leaf-deep, var(--tk-leaf-deep, #1f3d2c));
}
@media (max-width: 480px) {
  .tk-tokebot-popup {
    --tokebot-popup-font-size: var(--tokebot-popup-font-size-mobile);
    --tokebot-popup-side-padding: 12px;
    --tokebot-popup-bottom-padding: 12px;
  }
  .tk-tokebot-popup-card { max-width: 100%; border-radius: 18px; }
  .tk-tokebot-popup-hero { padding: 16px 14px 10px; }
  .tk-tokebot-popup-body { padding: 10px 14px 12px; }
}

/* ============================================================
   Founder PASS 67 2026-05-02 — TokeBot signature presence animation.
   Four states (idle / thinking / typing / complete), driven by a
   data-tk-tokebot-state attribute on the button. Theme tokens only —
   no hardcoded green — so NetBics + TikToke render natively in their
   own palettes. Reduced-motion strips the orbit + ember and keeps a
   slow breathing pulse only.
   ============================================================ */
.tk-tbp {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: 32px;
  height: 32px;
  flex-shrink: 0;
}
/* Founder PASS 68 2026-05-02 (signature animation size variants):
   the same SVG component scales cleanly to four contexts. inline mini
   beside chat avatars (small), launcher button (medium/floating),
   and the chat/search popup hero (popup). */
.tk-tbp[data-tk-tbp-size="small"]    { width: 20px;  height: 20px; }
.tk-tbp[data-tk-tbp-size="medium"]   { width: 32px;  height: 32px; }
.tk-tbp[data-tk-tbp-size="floating"] { width: 32px;  height: 32px; }
.tk-tbp[data-tk-tbp-size="popup"]    { width: 132px; height: 132px; }
.tk-tbp-svg {
  width: 100%;
  height: 100%;
  overflow: visible;
}

/* Soft glow halo — calm breathing pulse */
.tk-tbp-glow {
  transform-origin: center;
  animation: tkTbpGlow 4.6s ease-in-out infinite;
  will-change: transform, opacity;
}
@keyframes tkTbpGlow {
  0%, 100% { opacity: 0.45; transform: scale(0.95); }
  50%      { opacity: 0.75; transform: scale(1.06); }
}

/* Orbit group — rotates around the center; ribbons are dashed
   circles so they read as arc-segments (smoke-strand / terpene
   swirl), not full rings. */
.tk-tbp-orbit {
  transform-origin: 32px 32px;
  animation: tkTbpRotate 6s linear infinite;
  opacity: 0.45;
  transition: opacity 380ms ease-out;
  will-change: transform;
}
.tk-tbp-ribbon {
  fill: none;
  stroke: var(--tk-leaf, var(--tk-leaf, #3a8f5a));
  stroke-linecap: round;
  stroke-width: 1.4;
  stroke-dasharray: 28 76;
  stroke-dashoffset: 0;
  animation: tkTbpRibbonShift 6s linear infinite;
}
.tk-tbp-ribbon-2 {
  stroke: var(--tk-leaf-deep, var(--tk-leaf-deep, #1f3d2c));
  stroke-width: 1.1;
  stroke-dasharray: 14 90;
  stroke-dashoffset: 30;
  animation-duration: 8s;
  animation-direction: reverse;
  opacity: 0.7;
}
@keyframes tkTbpRotate { to { transform: rotate(360deg); } }
@keyframes tkTbpRibbonShift { to { stroke-dashoffset: -100; } }

/* Center emblem — gentle breath cycle */
.tk-tbp-emblem {
  transform-origin: 32px 32px;
  transform-box: fill-box;
  animation: tkTbpBreathe 4.8s ease-in-out infinite;
  will-change: transform;
}
@keyframes tkTbpBreathe {
  0%, 100% { transform: scale(1);     opacity: 1; }
  50%      { transform: scale(1.045); opacity: 0.97; }
}

/* Ember orbit — small accent that traces around the emblem.
   Idle: fully off (opacity 0). Thinking/typing: visible + rotates. */
.tk-tbp-ember-orbit {
  transform-origin: 32px 32px;
  animation: tkTbpEmberOrbit 5.2s linear infinite;
  opacity: 0;
  transition: opacity 320ms ease-out;
  will-change: transform, opacity;
}
.tk-tbp-ember {
  filter: drop-shadow(0 0 2.5px var(--tk-warm, #d68f3c));
}
@keyframes tkTbpEmberOrbit { to { transform: rotate(360deg); } }

/* THINKING — orbit faster, glow brighter, ember turns on. !important
   on duration so the slow-tier global *-rule's 1µs override doesn't
   neutralize the state-specific timing. Pattern matches pass 49. */
[data-tk-tokebot][data-tk-tokebot-state="thinking"] .tk-tbp-orbit       { animation-duration: 2.8s !important; opacity: 0.6; }
[data-tk-tokebot][data-tk-tokebot-state="thinking"] .tk-tbp-ribbon      { animation-duration: 2.8s !important; }
[data-tk-tokebot][data-tk-tokebot-state="thinking"] .tk-tbp-ribbon-2    { animation-duration: 4.4s !important; }
[data-tk-tokebot][data-tk-tokebot-state="thinking"] .tk-tbp-glow        { animation-duration: 3.2s !important; }
[data-tk-tokebot][data-tk-tokebot-state="thinking"] .tk-tbp-emblem      { animation-duration: 3.6s !important; }
[data-tk-tokebot][data-tk-tokebot-state="thinking"] .tk-tbp-ember-orbit { opacity: 0.85; animation-duration: 4.2s !important; }

/* TYPING — most active state; controlled, never frantic */
[data-tk-tokebot][data-tk-tokebot-state="typing"] .tk-tbp-orbit       { animation-duration: 1.6s !important; opacity: 0.78; }
[data-tk-tokebot][data-tk-tokebot-state="typing"] .tk-tbp-ribbon      { animation-duration: 1.6s !important; }
[data-tk-tokebot][data-tk-tokebot-state="typing"] .tk-tbp-ribbon-2    { animation-duration: 2.6s !important; }
[data-tk-tokebot][data-tk-tokebot-state="typing"] .tk-tbp-glow        { animation-duration: 2s !important; }
[data-tk-tokebot][data-tk-tokebot-state="typing"] .tk-tbp-emblem      { animation-duration: 2.2s !important; }
[data-tk-tokebot][data-tk-tokebot-state="typing"] .tk-tbp-ember-orbit { opacity: 1; animation-duration: 2.4s !important; }

/* COMPLETE — settle: orbit slows to idle speed, ember fades out, and
   a one-time ring-trace sweep draws around the emblem to visually say
   "answer ready". Founder's spec: "a faint ring trace that completes a
   loop when answer is ready" + "a slight sheen pass on transition from
   thinking → final answer". The trace uses stroke-dasharray + a single
   keyframe so it only fires once per complete state. */
[data-tk-tokebot][data-tk-tokebot-state="complete"] .tk-tbp-orbit       { animation-duration: 6s !important; opacity: 0.45; transition: opacity 600ms ease-out; }
[data-tk-tokebot][data-tk-tokebot-state="complete"] .tk-tbp-ribbon      { animation-duration: 6s !important; }
[data-tk-tokebot][data-tk-tokebot-state="complete"] .tk-tbp-ember-orbit { opacity: 0; transition: opacity 600ms ease-out; }
[data-tk-tokebot][data-tk-tokebot-state="complete"] .tk-tbp-ringtrace {
  animation: tkTbpRingTrace 700ms ease-out 1 forwards !important;
}
.tk-tbp-ringtrace {
  fill: none;
  stroke: var(--tk-leaf, var(--tk-leaf, #3a8f5a));
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-dasharray: 188; /* circumference 2*PI*30 ≈ 188 */
  stroke-dashoffset: 188;
  opacity: 0;
}
@keyframes tkTbpRingTrace {
  0%   { stroke-dashoffset: 188; opacity: 0; }
  20%  { opacity: 0.85; }
  100% { stroke-dashoffset: 0;   opacity: 0; }
}

/* Reduced motion — keep only the breathing glow */
@media (prefers-reduced-motion: reduce) {
  .tk-tbp-orbit,
  .tk-tbp-ribbon,
  .tk-tbp-ember-orbit { animation: none !important; }
  .tk-tbp-orbit       { opacity: 0.32 !important; }
  .tk-tbp-ember-orbit { opacity: 0 !important; }
  .tk-tbp-glow        { animation-duration: 7s !important; }
  .tk-tbp-emblem      { animation-duration: 7s !important; }
}
.tk-tokebot-label { display: grid; line-height: 1.1; text-align: left; }
.tk-tokebot-label strong { font-size: 14px; letter-spacing: 0.1em; }
.tk-tokebot-label em { font-style: normal; font-size: 11px; color: var(--tk-muted); }
.tk-scroll-top {
  position: fixed;
  right: var(--tk-scroll-top-right-desktop, 22px);
  bottom: var(--tk-scroll-top-bottom-desktop, 92px);
  z-index: 41;
  width: 44px;
  height: 44px;
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 22%, transparent);
  border-radius: 999px;
  background: var(--tk-leaf-deep);
  color: var(--tk-paper);
  display: inline-grid;
  place-items: center;
  cursor: pointer;
  box-shadow: 0 14px 30px rgba(20,20,18,0.22);
  opacity: 0;
  transform: translateY(8px) scale(0.96);
  pointer-events: none;
  /* Founder LIVE EDIT BLOCK 2026-04-30 (item 6 — shared floating fade):
     scroll-to-top uses the same fade-in/fade-out vars as Tokebot. Fade-
     out timing is the default; fade-in timing wins when data-visible
     becomes "true". */
  transition: opacity var(--tk-floating-fade-out-ms, var(--tk-scroll-top-fade-ms, .22s)) var(--tk-floating-fade-easing, ease), transform var(--tk-floating-fade-out-ms, var(--tk-scroll-top-fade-ms, .22s)) var(--tk-floating-fade-easing, ease), box-shadow .16s ease;
}
.tk-scroll-top[hidden] {
  display: inline-grid;
}
body[data-tk-performance="slow"][data-tk-animations="on"]:not([data-tk-page-hidden="true"]) .tk-scroll-top {
  /* Founder responsive pass 2026-04-29: performance mode may flatten heavy
     decorative motion, but the scroll-to-top control still needs the requested
     opacity fade unless the user explicitly disables animations/reduced motion. */
  transition: opacity var(--tk-floating-fade-out-ms, var(--tk-scroll-top-fade-ms, .22s)) var(--tk-floating-fade-easing, ease), transform var(--tk-floating-fade-out-ms, var(--tk-scroll-top-fade-ms, .22s)) var(--tk-floating-fade-easing, ease), box-shadow .16s ease !important;
}
.tk-scroll-top[data-visible="true"] {
  /* Founder LIVE EDIT BLOCK 2026-04-30 (item 6 — fade-in vs fade-out
     timing): when becoming visible, use --tk-floating-fade-in-ms; the
     base rule's fade-out timing is overridden to fade-in here. */
  transition: opacity var(--tk-floating-fade-in-ms, var(--tk-scroll-top-fade-ms, .22s)) var(--tk-floating-fade-easing, ease), transform var(--tk-floating-fade-in-ms, var(--tk-scroll-top-fade-ms, .22s)) var(--tk-floating-fade-easing, ease), box-shadow .16s ease;
  /* Founder LIVE EDIT BLOCK 2026-04-30 (TOKEBOT black overlay removal —
     scroll-top defensive): the previous 16px-y / 32px-blur dark drop
     shadow at 28% opacity could read as a soft horizontal band on
     small viewports right next to TOKEBOT. We trade the heavy shadow
     for a tight inset highlight + a small contained outer shadow that
     can't extend across the screen. The button still pops visibly
     without producing a screen-wide dark strip. */
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0) scale(1);
  box-shadow: 0 4px 10px rgba(20,20,18,0.18), inset 0 1px 0 rgba(255,255,255,0.16);
}
.tk-scroll-top:hover {
  transform: translateY(-2px);
}

/* Founder LIVE EDIT BLOCK 2026-04-30 (Legal AI change-notification banner):
   the global "Our Privacy Policy has been updated" banner sits above the
   sticky header. It uses the leaf-deep platform palette (no blue accents),
   surfaces once per session per legalVersion, and is dismissible. When
   dismissed the controller writes the current legalVersion into
   sessionStorage so the banner stays gone until Legal AI republishes a
   newer legalVersion. z-index sits above sticky header (100) but below
   age gate (150) so an open age gate still wins. */
/* Founder LIVE EDIT 2026-05-01 (legal banner UI refinement): single-line,
   sentence-case copy, centered, lighter-green pill on the verb. The
   dismiss button is positioned absolutely on the right edge so the
   pill+message pair stays VISUALLY centered within the viewport on both
   desktop and mobile (a flex-row layout with the dismiss in the same
   flow would push the centered content slightly off-center by the
   dismiss button's width). The mobile media query reduces font-size to
   ~0.9x and tightens padding so the banner stays single-line on phones
   without needing JS measurement. White-space:nowrap on the link
   prevents wrapping unless the viewport is genuinely too narrow to fit
   "See updated privacy policy" — at ≤340px viewports the message will
   wrap (acceptable per Founder's "extremely small screens" exception). */
/* Founder LIVE EDIT 2026-05-01 — PRIVACY UPDATE BAR fix.
   The prior banner had z-index:110 which made it stack-context-elevated
   above the sticky header (z-index:100), causing it to "feel like a
   modal layer" when the header rendered. The fix:
     • position: relative (in document flow), NO z-index — the banner
       takes natural block height at the very top of <body>, sitting
       above .tk-header by document order; .tk-header's sticky behavior
       starts only after the user scrolls past the banner so the banner
       reads as a true top-of-site announcement bar that pushes content
       downward, never overlays it.
     • dismissibleAside CSS lets the dismiss animation collapse the
       banner's height smoothly so the rest of the page slides back up
       without a jump cut. The duration + easing come from the JSON
       config (siteInfo.json#legalBanner.animation) and are injected as
       CSS variables before paint.
     • Hover underline removed (Founder PART 2: 'no underline on link').
       The full sentence is the click target. */
/* Founder TIKTOKE MENU/LOGO/TITLE position-lock pass 2026-05-03 —
   pre-paint hide of the prerendered legal banner. The server-side
   boot script sets body[data-tk-legal-banner-acked-pre="true"] BEFORE
   first paint when sessionStorage[dismissedKey] equals the current
   legalVersion, OR when buildDemoBootState already knew this user had
   acked. Hiding via display:none means zero flow contribution and zero
   layout shift. Specificity beats the .tk-legal-banner rule below. */
body[data-tk-legal-banner-acked-pre="true"] [data-tk-legal-banner],
body[data-tk-legal-banner-acked-pre="true"] .tk-legal-banner {
  display: none !important;
}
.tk-legal-banner {
  /* Founder LIVE EDIT 2026-05-01 (pass 50 — privacy link visibility):
     scope --tk-link-color to the banner's paper foreground so the
     ".tk-page :link, .tk-page :visited { color: var(--tk-link-color) }"
     rule (specificity 0,1,1) doesn't paint the link in dark green on
     a dark green background. Any :link/:visited inside the banner now
     inherits the cream color via the cascaded variable. */
  --tk-link-color: var(--tk-paper, #f7f5f0);
  /* Founder LIVE EDIT 2026-05-01 (FIRST VISIT STACK ORDER FIX —
     PRIVACY BANNER LAYER): privacy banner now sits at z-index 5000
     per Founder's strict hierarchy (above the menu/header at 4000,
     below all popups/modals at 8500+). Position remains relative
     to flow document order at the very top of <body> so the rest
     of the page slides downward by the banner's height — this
     preserves the existing "top-of-site announcement bar" behavior
     while making the explicit z-index work via the relative
     positioning context. The banner must visually sit BEHIND any
     active age check / location picker (z-index 9000+), and ABOVE
     the menu (4000). */
  position: relative;
  z-index: 5000;
  display: block;
  width: 100%;
  padding: 8px clamp(36px, 6vw, 48px);
  background: var(--tk-leaf-deep, var(--tk-leaf-deep, #1f3d2c));
  color: var(--tk-paper, #f7f5f0);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0;
  box-shadow: 0 3px 10px color-mix(in srgb, var(--tk-leaf-deep) 16%, transparent);
  text-align: center;
  overflow: hidden;
  max-height: 240px; /* enough room for two-line wrap on tiny screens */
  opacity: 1;
  transition: max-height var(--tk-legal-banner-collapse-ms, 280ms) var(--tk-legal-banner-easing, cubic-bezier(0.4, 0, 0.2, 1)),
              opacity var(--tk-legal-banner-collapse-ms, 280ms) var(--tk-legal-banner-easing, cubic-bezier(0.4, 0, 0.2, 1)),
              padding var(--tk-legal-banner-collapse-ms, 280ms) var(--tk-legal-banner-easing, cubic-bezier(0.4, 0, 0.2, 1)),
              transform var(--tk-legal-banner-collapse-ms, 280ms) var(--tk-legal-banner-easing, cubic-bezier(0.4, 0, 0.2, 1));
}
.tk-legal-banner[data-tk-collapsing="true"] {
  /* Founder PART 1 'page slides back upward smoothly': collapsing the
     max-height + padding to 0 lets siblings move up in flow. */
  max-height: 0;
  padding-top: 0;
  padding-bottom: 0;
  opacity: 0;
  pointer-events: none;
}
/* Founder LIVE EDIT 2026-05-01 (pass 51 — privacy banner smooth slide-in):
   when the banner first mounts it must NEVER pop in instantly. We start
   the node with data-tk-entering="true" (max-height collapsed, opacity 0,
   translateY -100%), then on the next frame demo.js removes the attribute
   so the existing transitions on max-height/padding/opacity ease the
   banner from collapsed → full height. The translate3d adds a subtle
   downward slide so the motion reads as "sliding into place" instead of
   just expanding the box. */
.tk-legal-banner[data-tk-entering="true"] {
  max-height: 0;
  padding-top: 0;
  padding-bottom: 0;
  opacity: 0;
  transform: translate3d(0, -100%, 0);
  pointer-events: none;
}
.tk-legal-banner-link {
  display: inline-flex;
  align-items: center;
  /* Founder LIVE EDIT 2026-05-01 (PRIVACY BANNER SPACING — precision
     fix): tightened the gap between the green "See" pill and the
     "updated privacy policy" message. Prior 8px gap read as a wide
     pause between the two elements; 4px keeps the two visibly
     separated as distinct UI without making them feel detached. */
  gap: 4px;
  color: inherit;
  text-decoration: none; /* Founder: no link underline */
  white-space: nowrap;
  max-width: 100%;
}
.tk-legal-banner-link:hover,
.tk-legal-banner-link:focus,
.tk-legal-banner-link:focus-visible,
.tk-legal-banner-link:hover .tk-legal-banner-message,
.tk-legal-banner-link:focus .tk-legal-banner-message,
.tk-legal-banner-link:focus-visible .tk-legal-banner-message {
  text-decoration: none;
}
@media (prefers-reduced-motion: reduce) {
  .tk-legal-banner { transition: none; }
}
.tk-legal-banner-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Founder Pass 10.6.x 2026-05-04 — padding is JSON-driven. Source
     of truth: core/cannabis/content/siteInfo.json#legalBanner.pillPadding
     The server pre-paint <style data-tk-legal-banner-pill-padding>
     writes --tk-legal-banner-pill-desktop-padding and
     --tk-legal-banner-pill-mobile-padding from that JSON; this rule
     consumes the desktop var. The CSS fallback "3px 5px 3px 7px"
     ONLY applies if the JSON / boot script is absent. To change
     padding, edit the JSON — not this CSS. */
  padding: var(--tk-legal-banner-pill-desktop-padding, 3px 5px 3px 7px);
  border-radius: 999px;
  /* Founder Pass 10.6.x 2026-05-04 — founder rule (verbatim):
     "Dark mode 'SEE' pill is using the banner color and blends in.
     It must use the dark-theme pill token, not the banner token."
     Light mode keeps --tk-leaf (banner=--tk-leaf-deep, pill=--tk-leaf
     so the pill is visibly lighter against the banner). Dark mode
     collapses --tk-leaf-deep onto --tk-leaf, making banner and pill
     identical and the pill invisible. Routed through a dedicated
     --tk-see-pill-bg / --tk-see-pill-fg token; the dark-mode block
     below overrides them so the pill stands out (pale paper bg
     with leaf-deep text) instead of blending with the banner. */
  background: var(--tk-see-pill-bg, var(--tk-leaf));
  color: var(--tk-see-pill-fg, var(--tk-paper));
  font-size: 11px;
  font-weight: 800;
  letter-spacing: .02em;
  line-height: 1.2;
  flex-shrink: 0;
}
:root[data-theme="dark"] {
  --tk-see-pill-bg: var(--tk-paper);
  --tk-see-pill-fg: var(--tk-leaf-deep);
}
:root[data-theme="dark"] .tk-mobile-drawer-link[data-menu-style="gameEntry"] {
  /* Dark mode keeps higher opacity since the dark drawer eats more
     of the smoke contrast than the light drawer does. */
  --tk-game-entry-smoke-opacity: 0.55;
  --tk-game-entry-pulse-opacity: 0.62;
}
.tk-legal-banner-message {
  font-weight: 600;
  font-size: 13px;
  line-height: 1.25;
}
.tk-legal-banner-dismiss {
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
  background: transparent;
  border: 0;
  color: inherit;
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  padding: 4px 8px;
  opacity: 0.78;
  transition: opacity .12s;
}
.tk-legal-banner-dismiss:hover { opacity: 1; }
@media (max-width: 720px) {
  .tk-legal-banner {
    padding: 6px 36px 6px 12px;
    font-size: 11.7px;
    box-shadow: 0 2px 8px color-mix(in srgb, var(--tk-leaf-deep) 14%, transparent);
  }
  /* Founder LIVE EDIT 2026-05-01 (PRIVACY BANNER SPACING — mobile):
     mirror the desktop tightening. 4px on mobile keeps "See" pill and
     message visually paired without the prior wide-gap pause. */
  .tk-legal-banner-link { gap: 4px; }
  .tk-legal-banner-pill {
    /* Founder Pass 10.6.x 2026-05-04 — mobile padding is also JSON-
       driven. Source of truth: siteInfo.json#legalBanner.pillPadding
       .mobile. Fallback below mirrors the prior literal, but the
       canonical value comes from JSON. */
    padding: var(--tk-legal-banner-pill-mobile-padding, 2px 4px 2px 6px);
    font-size: 10px;
  }
  .tk-legal-banner-message {
    font-size: 11.7px;
    line-height: 1.2;
  }
  .tk-legal-banner-dismiss {
    right: 6px;
    font-size: 18px;
    padding: 2px 6px;
  }
}

/* =============== SIGN-IN MODAL =============== */
.tk-signin-modal {
  border: 0; background: transparent; padding: 0; max-width: 92vw;
}
.tk-signin-modal::backdrop { background: rgba(15,15,12,0.55); backdrop-filter: blur(6px); }
.tk-signin-card {
  width: clamp(280px, 92vw, 460px);
  background: var(--tk-paper); border-radius: var(--tk-radius-lg); padding: 22px;
  box-shadow: 0 24px 60px rgba(0,0,0,0.3);
  display: grid; gap: 12px;
}
.tk-signin-head { display: flex; justify-content: space-between; align-items: center; }
.tk-signin-head h2 { margin: 0; font-size: 18px; }
.tk-signin-close { background: transparent; border: 0; font-size: 22px; color: var(--tk-muted); cursor: pointer; }
.tk-signin-close:hover { color: var(--tk-ink); }
.tk-signin-body { margin: 0; color: var(--tk-ink-soft); font-size: 14px; }
.tk-signin-provider {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  width: 100%;
  padding: 12px 16px; font: inherit; font-size: 15px; font-weight: 600;
  border-radius: 12px; cursor: pointer;
  border: 1px solid var(--tk-line);
  background: var(--tk-paper); color: var(--tk-ink);
  transition: transform .12s, border-color .15s, background .15s;
}
.tk-signin-provider:hover { transform: translateY(-1px); border-color: var(--tk-leaf); }
.tk-signin-provider:disabled { opacity: 0.65; cursor: default; transform: none; }
.tk-signin-apple   { background: #111; color: #fff; border-color: #111; }
.tk-signin-apple:hover { background: #000; border-color: #000; }
.tk-signin-google  { background: #fff; color: #161613; border-color: var(--tk-line-strong); }
.tk-signin-founder { background: var(--tk-leaf); color: #fff; border-color: var(--tk-leaf); }
.tk-signin-founder:hover { background: var(--tk-leaf-deep); border-color: var(--tk-leaf-deep); }
.tk-signin-hint { margin: 0; color: var(--tk-muted); font-size: 12px; text-align: center; }
.tk-auth-mode-panel {
  display: grid;
  gap: 14px;
}
.tk-auth-choice-card {
  position: relative;
  display: grid;
  grid-template-columns: minmax(86px, 0.46fr) minmax(0, 1fr);
  align-items: center;
  gap: 14px;
  padding: 16px;
  border: 1px solid color-mix(in srgb, var(--tk-line) 72%, transparent);
  border-radius: 22px;
  background:
    radial-gradient(circle at 12% 8%, color-mix(in srgb, var(--tk-leaf-light) 18%, transparent), transparent 36%),
    color-mix(in srgb, var(--tk-paper) 84%, transparent);
  box-shadow: 0 16px 32px color-mix(in srgb, var(--tk-leaf-deep) 10%, transparent);
  overflow: visible;
}
.tk-auth-choice-customer {
  grid-template-columns: 1fr;
  justify-items: center;
  text-align: left;
  padding-top: 6px;
}
.tk-auth-choice-customer .tk-auth-choice-popout {
  min-height: 94px;
  height: 94px;
  margin-top: -26px;
  margin-bottom: 10px;
  transform: translateY(0);
}
.tk-auth-choice-customer .tk-auth-choice-copy {
  width: 100%;
}
.tk-auth-choice-card h3 {
  margin: 0 0 4px;
  font-size: 16px;
  color: var(--tk-ink);
}
.tk-auth-choice-card p {
  margin: 0;
  color: var(--tk-ink-soft);
  font-size: 12px;
  line-height: 1.45;
}
.tk-auth-choice-popout {
  position: relative;
  min-height: 92px;
  display: grid;
  place-items: center;
  transform: translateY(-10px) translateX(-4px);
  filter: drop-shadow(0 18px 18px color-mix(in srgb, var(--tk-leaf-deep) 16%, transparent));
}
.tk-auth-choice-visual {
  width: min(132px, 35vw);
  height: auto;
  display: block;
}
.tk-auth-choice-visual-customer {
  width: min(142px, 48vw);
  max-height: 112px;
  background: transparent;
}
.tk-auth-phone-signup {
  display: grid;
  gap: 8px;
  margin-top: 12px;
}
.tk-auth-phone-signup label {
  display: grid;
  gap: 5px;
  color: var(--tk-muted);
  font-size: 11px;
  font-weight: 900;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.tk-auth-phone-signup input {
  width: 100%;
  min-width: 0;
  border: 1px solid var(--tk-line);
  border-radius: 14px;
  padding: 11px 12px;
  font: inherit;
  color: var(--tk-ink);
  background: #fff;
  box-sizing: border-box;
}
.tk-auth-phone-submit {
  border: 0;
  border-radius: 999px;
  padding: 10px 14px;
  font: inherit;
  font-weight: 950;
  color: #fff;
  background: var(--tk-leaf-deep);
  cursor: pointer;
}
.tk-auth-phone-signup small {
  min-height: 14px;
  color: var(--tk-status-offline);
  font-size: 11px;
}
.tk-auth-provider-grid {
  display: grid;
  gap: 8px;
  margin-top: 12px;
}
.tk-signup-provider {
  width: 100%;
  min-height: 42px;
}
.tk-signup-facebook {
  background: #1f5ea8;
  color: #fff;
  border-color: #1f5ea8;
}
.tk-auth-claim-cta {
  margin-top: 12px;
  border: 0;
  border-radius: 999px;
  padding: 10px 16px;
  background: var(--tk-leaf);
  color: #fff;
  font-weight: 950;
  cursor: pointer;
  box-shadow: 0 12px 22px color-mix(in srgb, var(--tk-leaf) 22%, transparent);
}
.tk-auth-claim-flow .tk-business-referral {
  margin-top: 2px;
}
.tk-signin-hint-inline {
  margin: 0;
  color: var(--tk-muted);
  font-size: 12px;
  text-align: center;
}
@media (max-width: 560px) {
  .tk-auth-choice-card {
    grid-template-columns: 92px minmax(0, 1fr);
    padding: 14px;
  }
  .tk-auth-choice-customer {
    grid-template-columns: 1fr;
    gap: 0;
    padding-top: 8px;
  }
  .tk-auth-choice-customer .tk-auth-choice-popout {
    min-height: 88px;
    height: 88px;
    margin-top: -24px;
    margin-bottom: 14px;
    transform: none;
  }
  .tk-auth-choice-customer .tk-auth-choice-visual-customer {
    width: min(132px, 44vw);
  }
  .tk-auth-choice-popout {
    min-height: 74px;
    transform: translateY(-8px) translateX(-8px);
  }
  .tk-auth-choice-visual {
    width: 112px;
  }
  .tk-auth-choice-customer .tk-auth-choice-popout {
    min-height: 88px;
    height: 88px;
    margin-top: -24px;
    margin-bottom: 14px;
    transform: none;
  }
  .tk-auth-choice-customer .tk-auth-choice-visual-customer {
    width: min(132px, 44vw);
  }
  .tk-auth-provider-grid {
    gap: 7px;
  }
}

.tk-gate {
  /* Founder LIVE EDIT 2026-05-01 (FIRST VISIT STACK ORDER FIX —
     STRICT Z-INDEX HIERARCHY): the .tk-gate root container hosts BOTH
     the age check card (data-tk-gate-age) and the location picker
     card (data-tk-gate-location). Founder's exact mandate:
       Location Picker: 9999 (highest)
       Age Check:       9000
     Since the two cards are siblings inside one fixed-position
     parent and only one shows at a time, the parent .tk-gate sits
     at z-index 9000 (Age Check baseline). When the location card
     becomes the active card, the .tk-gate-card[data-tk-gate-location]
     rule below escalates the parent isolation to 9999 via z-index
     stacking on the active card itself, so the Location Picker is
     ALWAYS topmost over every other layer (privacy banner 5000,
     header 4000, spin wheel 8500). The fixed/inset:0 layer with
     backdrop-filter still covers everything below it. */
  position: fixed;
  inset: 0;
  z-index: 9000;
  display: grid;
  place-items: center;
  padding: 20px;
  background: color-mix(in srgb, var(--tk-paper) 82%, transparent);
  backdrop-filter: blur(12px);
  isolation: isolate;
}
/* Location card escalates to 9999 — Founder: "Location Picker is
   ALWAYS topmost." When the gate is showing the location step,
   the parent .tk-gate is repurposed by raising its z-index from
   9000 (age) to 9999 (location). We do this via a body-level data
   hook (set by demo.js when the location step takes over) so the
   layer math stays declarative. */
body[data-tk-gate-step="location"] .tk-gate { z-index: 9999; }
.tk-gate[hidden] { display: none; }

/* Founder LIVE EDIT 2026-05-01 (FIRST VISIT STACK ORDER FIX —
   menu + banner gated behind active modal): when the gate is showing
   (body.tk-gate-open is set by demo.js), the privacy banner + the
   sticky header become non-interactive so the user cannot click
   through them. The gate's backdrop-filter blur already covers them
   visually; pointer-events: none + visibility: hidden complete the
   modal isolation per Founder's "Menu must NOT be clickable when a
   modal is active" + "Privacy banner must visually sit BEHIND
   active modals" rule. The same rule applies to body.tk-location-
   open (the city picker that pops after location denial — Founder's
   real-device report: "when the What city popup came, I could see
   the homepage menu, but it's supposed to be behind it"). */
body.tk-gate-open .tk-header,
body.tk-gate-open .tk-legal-banner,
body.tk-location-open .tk-header,
body.tk-location-open .tk-legal-banner {
  pointer-events: none;
  visibility: hidden;
}
/* Pass 74 — Founder: "ads are moving but mobile menu/carousel items
   are not". Root cause: tk-location-open body class lingers while
   the city picker is queued (after skip the picker can re-queue),
   and the visibility:hidden rule above hid the entire .tk-header
   including the .tk-categories-shell carousel. The picker has its
   own backdrop / modal isolation, so the underlying carousel does
   not need to be invisible — it just needs to be non-interactive
   while a modal is on top. This rule re-shows the category
   carousel regardless of body.tk-location-open / tk-gate-open. */
body.tk-gate-open .tk-categories-shell,
body.tk-gate-open .tk-categories,
body.tk-location-open .tk-categories-shell,
body.tk-location-open .tk-categories {
  visibility: visible !important;
  pointer-events: none;
}
/* Founder PASS 55 2026-05-02 (AGE CHECK no-bypass): block body scroll
   while the gate is open per Founder's spec — "scroll access behind
   modal" must not work. The fixed-position .tk-gate already covers the
   viewport visually; this rule prevents touchpad/wheel/keyboard scrolling
   the page behind it. Removed cleanly when demo.js calls finish() and
   strips body.tk-gate-open. */
body.tk-gate-open,
body.tk-location-open {
  overflow: hidden;
  overscroll-behavior: contain;
}
.tk-gate-card {
  position: relative;
  overflow: hidden;
  width: min(420px, 100%);
  display: grid;
  gap: 12px;
  padding: 24px;
  border-radius: 24px;
  background: var(--tk-paper);
  border: 1px solid var(--tk-line);
  box-shadow: var(--tk-shadow);
}
.tk-gate-card[hidden] { display: none; }
.tk-gate-card h2,
.tk-gate-card p { margin: 0; }
/* Founder live edit 2026-04-30: center every text element inside the age
   confirmation card (kicker, headline, body copy, terms label, primary
   button label). Scoped to [data-tk-gate-age] so the sibling location
   card keeps its existing left-aligned layout. */
.tk-gate-card[data-tk-gate-age] { text-align: center; }
.tk-gate-card[data-tk-gate-age] .tk-order-kicker,
.tk-gate-card[data-tk-gate-age] h2,
.tk-gate-card[data-tk-gate-age] > p { text-align: center; }
/* Founder live edit 2026-04-30: the age confirmation checkbox + label sit on
   ONE LINE — checkbox immediately to the left of "I confirm I am the legal
   age in my province or territory", both centered as a single inline group.
   The label is now short (no embedded Privacy/Terms links) so wrapping
   should not happen at any reasonable card width. */
.tk-gate-card[data-tk-gate-age] .tk-age-terms {
  /* Founder live edit 2026-04-30 (LIVE EDIT BLOCK — age gate centering):
     checkbox row stays as a single flex row so the checkbox sits on the
     same first line as the start of the consent text. The text itself is
     smaller than the body copy, can wrap to multiple lines, and each line
     reads center-aligned to match the rest of the card. align-items:start
     keeps the checkbox optically anchored to the first line cap height,
     not floating in the vertical middle of a multi-line block. */
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  justify-content: center;
  align-items: flex-start;
  text-align: center;
  gap: 8px;
  width: 100%;
  max-width: 100%;
  font-size: 12px;
  line-height: 1.45;
  color: var(--tk-ink-soft);
}
.tk-gate-card[data-tk-gate-age] .tk-age-terms > input {
  flex: 0 0 auto;
  margin: 3px 0 0;
}
.tk-gate-card[data-tk-gate-age] .tk-age-terms > span {
  flex: 1 1 auto;
  text-align: center;
  white-space: normal;
}
.tk-gate-card[data-tk-gate-age] .tk-age-terms a {
  color: var(--tk-leaf-deep);
  font-weight: 800;
}
.tk-gate-card[data-tk-gate-age] .tk-gate-primary { justify-self: center; }
/* Founder live edit 2026-04-30: Privacy/Terms agreement copy lives BELOW the
   Continue button as a separate paragraph, smaller and muted, with the
   Privacy Policy / Terms of Service words rendered as links. */
.tk-gate-card[data-tk-gate-age] .tk-age-legal {
  margin: 0;
  text-align: center;
  color: var(--tk-muted);
  font-size: 10px;
  letter-spacing: 0.01em;
  line-height: 1.45;
  opacity: 0.9;
}
.tk-gate-card[data-tk-gate-age] .tk-age-legal a {
  color: var(--tk-leaf-deep);
  font-weight: 900;
}
.tk-age-smoke {
  position: fixed;
  left: 50%;
  top: -18vh;
  width: min(72vw, 620px);
  height: min(42vh, 380px);
  transform: translateX(-50%) scale(var(--tk-age-smoke-scale-start, 0.78));
  opacity: 0;
  pointer-events: none;
  z-index: -1;
  filter: blur(var(--tk-age-smoke-blur, 18px));
  background:
    radial-gradient(ellipse at 35% 36%, rgba(255,255,255,0.72), transparent 48%),
    radial-gradient(ellipse at 58% 42%, rgba(214,222,214,0.54), transparent 46%),
    radial-gradient(ellipse at 48% 68%, rgba(188,197,184,0.34), transparent 52%);
}
.tk-age-smoke.tk-age-smoke-play {
  animation: tkAgeSmokePuff var(--tk-age-smoke-duration, 2400ms) ease-out both;
}
.tk-age-terms {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 8px;
  align-items: start;
  color: var(--tk-ink-soft);
  font-size: 12px;
  line-height: 1.35;
}
.tk-age-terms a {
  color: var(--tk-leaf-deep);
  font-weight: 900;
}
.tk-gate-primary:disabled {
  opacity: 0.54;
  cursor: not-allowed;
}
body[data-tk-animations="off"] .tk-age-smoke {
  animation: none !important;
  display: none;
}
@media (prefers-reduced-motion: reduce) {
  .tk-age-smoke { animation: none !important; display: none; }
}
@keyframes tkAgeSmokePuff {
  0% {
    opacity: 0;
    transform: translate(-50%, 0) scale(var(--tk-age-smoke-scale-start, 0.78));
  }
  18% {
    opacity: var(--tk-age-smoke-opacity, 0.68);
  }
  100% {
    opacity: 0;
    transform: translate(calc(-50% + var(--tk-age-smoke-drift-x, 8vw)), 128vh) scale(var(--tk-age-smoke-scale-end, 1.45));
  }
}
.tk-location-save {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  color: var(--tk-ink-soft);
  font-size: 13px;
}
.tk-location-save select {
  border: 1px solid var(--tk-line);
  border-radius: 999px;
  padding: 6px 10px;
  background: var(--tk-bg);
  color: var(--tk-ink);
}
.tk-gate-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  flex-wrap: wrap;
}
.tk-gate-primary,
.tk-gate-secondary {
  border: 0;
  border-radius: 999px;
  padding: 10px 16px;
  font: inherit;
  font-weight: 800;
  cursor: pointer;
}
.tk-gate-primary { background: var(--tk-leaf); color: var(--tk-paper); }
.tk-gate-secondary { background: var(--tk-leaf-soft); color: var(--tk-leaf-deep); }

/* Founder HARD CORRECTION 2026-05-03 — spin-wheel admin: per-segment
   color pickers + theme-token preset chips. Founder rule: "put
   ability to choose colors on spin wheel text for each one. make
   it all theme colors, and opposite color (orange for example)".
   The text input is the source of truth (saved as-is). The
   <input type="color"> sits next to it for custom hex picks. The
   .tk-spin-color-presets row is a flex of round chips coloured by
   --c (set inline per chip) so the founder can click a brand
   token and it becomes "var(--tk-leaf)" / "var(--tk-warm)" etc.
   in the value. Each chip is 16×16 with a thin border. */
.tk-spin-color-row {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}
.tk-spin-color-row > input[type="text"] {
  flex: 1 1 140px;
  min-width: 0;
}
.tk-spin-color-row > input[type="color"] {
  width: 28px;
  height: 28px;
  border-radius: 6px;
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 16%, transparent);
  padding: 0;
  cursor: pointer;
  background: var(--tk-paper);
}
.tk-spin-color-presets {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex-wrap: wrap;
}
.tk-spin-color-presets button {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 22%, transparent);
  padding: 0;
  margin: 0;
  cursor: pointer;
  background: var(--c, transparent);
  transition: transform .12s;
}
.tk-spin-color-presets button:hover {
  transform: scale(1.18);
}

/* =============== FOOTER =============== */
/* Founder HARD CORRECTION 2026-05-03 — founder rule: "make sure
   it uses 'SiteName', and centre all that text". The <strong>
   inside the footer now carries data-tk-brand-name so the existing
   setAllText("[data-tk-brand-name]", resolvedWordmark) call (run.js
   ~line 6534) writes the correct brand into it (TIKTOKE on
   tiktoke, NETBICS on netbics). Text-align center on .tk-footer p
   centers the whole paragraph. */
.tk-footer { color: var(--tk-muted); font-size: 12px; padding: 8px 0 0; }
.tk-footer p { text-align: center; }
.tk-footer strong { color: var(--tk-ink); }

/* =============== HOMEPAGE SHELL FOLLOW-UP ===============
   Pass origin: #passes.txt cannabis frontend full-section carry-forward.
   This block covers the related header/location/favorites/cart/notification
   systems Founder called out for /demo: desktop and mobile headers, location
   picker, signed-in controls, slideout cart, favorites page, 1–28 homepage
   rows, and quarter-star product display. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.tk-mobile-menu { display: none; }
.tk-header-row {
  position: relative;
  z-index: 1;
  /* Founder LIVE EDIT 2026-05-01 — HARD STOP / TRUE CENTER LOCK PASS:
     ATTEMPTED a 3-column [1fr][center auto][1fr] grid with explicit
     grid-column placements for every direct child to lock the center-
     stack to viewport center regardless of logo width. Playwright
     headless capture (centered_desktop_demo.png) showed the explicit
     placements broke the existing multi-row layout — direct children
     this rule didn't enumerate (e.g. tk-notifications-popover, hidden
     mobile drawer, mobile favorites action, dynamically-injected nav
     items) auto-flowed into wrong cells. ROLLED BACK to the
     pre-existing 5-column template here so production layout stays
     intact. Founder's PART 3 center-lock is therefore PARTIAL pending
     a focused header-row restructure that wraps logo+location in a
     LeftRail child and nav+search+categories in a CenterStack child,
     which would let the grid lock center reliably without per-child
     placement. The wrapper restructure is documented under
     #passesoutput.txt as the next pass's blocker. */
  grid-template-columns: auto auto minmax(300px, 1fr) minmax(260px, 1fr) auto;
}
.tk-main-menu {
  /* Founder LIVE EDIT BLOCK 2026-04-30 (desktop main-menu vertical offset
     + word-size limit removal): the menu can be shifted up/down via
     --tk-desktop-menu-vertical-offset (JSON-driven, multiples of 3px,
     range -48 to +48) so Founder can fine-tune where Delivery/Stores/etc.
     sit relative to the search bar without touching the header grid.
     Founder LIVE EDIT BLOCK 2026-04-30 (main menu horizontal-only scroll):
     the top main menu must scroll left/right ONLY. Vertical wheel/touch
     events used to bounce the nav up-down because overflow-y was the
     default (visible). Locking it down:
       - overflow-y: hidden          → kills vertical scroll
       - overscroll-behavior-y: none → kills vertical bounce/chain
       - touch-action: pan-x         → touch only pans horizontally
       - .tk-main-menu wheel handler (in demo.js) translates vertical
         wheel deltas into horizontal scroll so trackpads still work
         intuitively without ever moving the nav vertically. */
  display: flex;
  justify-content: flex-start;
  gap: 8px;
  min-width: 0;
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-y: none;
  overscroll-behavior-x: contain;
  touch-action: pan-x;
  scrollbar-width: none;
  transform: translateY(var(--tk-desktop-menu-vertical-offset, 0px));
}
.tk-main-menu::-webkit-scrollbar { display: none; }
.tk-main-menu-link {
  border: 0;
  background: transparent;
  color: var(--tk-leaf-deep);
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
  flex: 0 0 auto;
  cursor: pointer;
  text-decoration: none;
  padding: 6px 4px;
}
.tk-main-menu-link:hover { color: var(--tk-leaf); }
/* Founder zero-blocker live edit 2026-04-30: PLAY menu sparkle flows upward
   behind the text, must look high-end (gold + cream), and shuts off when
   global animations are disabled or prefers-reduced-motion is true.
   Values are config-fed via header.desktopMenu.playSparkle.* in homepage.json. */
.tk-main-menu-link[data-tk-play-sparkle="true"] {
  position: relative;
  isolation: isolate;
}
.tk-main-menu-link[data-tk-play-sparkle="true"] > span:not(.tk-play-sparkle-layer) {
  position: relative;
  z-index: 2;
}
.tk-play-sparkle-layer {
  position: absolute;
  inset: -6px -10px -2px -10px;
  z-index: 1;
  pointer-events: none;
  overflow: hidden;
  opacity: var(--tk-play-sparkle-opacity, 0.55);
  filter: blur(0.4px);
}
.tk-play-sparkle-dot {
  /* Founder LIVE EDIT BLOCK 2026-04-30 (item 1 — true infinite sparkle):
     each particle is positioned absolutely with per-particle CSS vars
     (--tk-play-sparkle-size, --tk-play-sparkle-peak-opacity,
     --tk-play-sparkle-duration-each, --tk-play-sparkle-delay,
     --tk-play-sparkle-drift, --tk-play-sparkle-rise) so particles drift,
     rise, fade, and loop on independent timelines without visual sync.
     Default values match the JSON (config-fed) but allow particles to
     render correctly even before per-particle vars are set by demo.js.
     Founder HARD CORRECTION 2026-05-03 — founder rule: "I CAN ONLY SEE
     THE ANIMATION AROUND THE WORD PLAY IN DARK MODE. MAKE THE PLAY IN
     LIGHT MODE HAVE GREEN ANIMATION COLOR". Default sparkle colors
     were gold/cream (rgba(225,198,92) / rgba(255,246,205)) which
     vanish on the cream page bg. New defaults pull from --tk-leaf so
     the sparkle is brand-green in light mode (visible against cream)
     and stays brand-blue on netbics. Dark mode override below
     restores the gold sparkle. */
  position: absolute;
  bottom: -6px;
  width: var(--tk-play-sparkle-size, 4px);
  height: var(--tk-play-sparkle-size, 4px);
  border-radius: 50%;
  background: radial-gradient(circle, var(--tk-play-sparkle-color-a, var(--tk-leaf, #3a8f5a)) 0%, var(--tk-play-sparkle-color-b, color-mix(in srgb, var(--tk-leaf) 50%, transparent)) 55%, transparent 75%);
  box-shadow: 0 0 6px var(--tk-play-sparkle-color-a, var(--tk-leaf, #3a8f5a));
  animation: tkPlaySparkleRise var(--tk-play-sparkle-duration-each, var(--tk-play-sparkle-duration, 4200ms)) cubic-bezier(.4,0,.6,1) infinite;
  animation-delay: var(--tk-play-sparkle-delay, 0ms);
  opacity: 0;
  will-change: transform, opacity;
}
.tk-play-sparkle-dot.is-star {
  /* Diamond/star shape via clip-path; the existing radial gradient still
     fills it so the gold-cream tones match the round particles. */
  border-radius: 0;
  clip-path: polygon(50% 0%, 60% 38%, 100% 50%, 60% 62%, 50% 100%, 40% 62%, 0% 50%, 40% 38%);
}
@keyframes tkPlaySparkleRise {
  0%   { transform: translate3d(0, 0, 0) scale(.6); opacity: 0; }
  18%  { opacity: var(--tk-play-sparkle-peak-opacity, .8); }
  55%  { transform: translate3d(calc(var(--tk-play-sparkle-drift, 0%) * 0.5), calc(var(--tk-play-sparkle-rise, -42px) * 0.55), 0) scale(1); opacity: var(--tk-play-sparkle-peak-opacity, .8); }
  82%  { opacity: calc(var(--tk-play-sparkle-peak-opacity, .8) * 0.45); }
  100% { transform: translate3d(var(--tk-play-sparkle-drift, 0%), var(--tk-play-sparkle-rise, -42px), 0) scale(.4); opacity: 0; }
}
body[data-tk-animations="off"] .tk-play-sparkle-layer,
body[data-tk-animations="off"] .tk-play-sparkle-dot {
  animation: none !important;
  opacity: 0 !important;
}
@media (prefers-reduced-motion: reduce) {
  .tk-play-sparkle-layer,
  .tk-play-sparkle-dot {
    animation: none !important;
    opacity: 0 !important;
  }
}
@media (max-width: 720px) {
  .tk-play-sparkle-layer { display: none; }
}
.tk-main-menu-link[data-active="true"] {
  /* Founder nav focus live edit 2026-04-29: active primary nav state must be
     visible for the responsive focus helper without underlines, blue, or a
     redesigned header. The helper reads data-active from config-owned route
     rules and uses this subtle green state as its visual anchor. */
  color: var(--tk-leaf-deep);
  background: color-mix(in srgb, var(--tk-leaf-soft) 72%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tk-leaf) 18%, transparent);
  border-radius: 10px;
}

@media (min-width: 981px) {
  .tk-header-row {
    display: grid;
    /* Founder LIVE EDIT 2026-05-01 (MENU SYSTEM CORRECTION — TRUE
       CENTER LOCK): the prior layout used
         minmax(230px, var(--tk-desktop-brand-block-width)) minmax(0, 1fr) auto
       which sized the center column as "remaining space" between the
       brand block and the actions column. That meant the center stack
       (top nav + search + green category bar) drifted whenever the
       logo width or actions width changed — Founder's exact complaint:
       "Menu LOOKS centered, but is not actually locked center."
       NEW: symmetric three-column grid 1fr | auto | 1fr forces the
       middle (center-stack) column to viewport center because the
       two flexible side columns mirror each other. minmax(0, 1fr)
       lets the side columns shrink below content size if needed
       without growing past their share. The existing
       --tk-desktop-brand-block-width var is preserved as a min on
       BOTH side columns so the visual weight stays balanced even
       when one side has more content than the other. Logo + Location
       sit in column 1, Header Actions sit in column 3, neither can
       push the center stack off viewport center. */
    /* Founder HARD CORRECTION 2026-05-03 (rev 2) — founder Z/X/Y/A/B
       pass: "center menu stays centered no matter what the
       logo/title and right icons do". minmax(min, 1fr) wasn't
       enforcing equal flex distribution because grid's auto-track
       sizing collapses one side when the other reaches min. Fix:
       both side cols are now EXACTLY var(--tk-header-side-col-min)
       (computed by JS to max(brand, actions) intrinsic widths).
       Center auto column is then mathematically forced to the
       middle of row content. The wrapper uses justify-content:
       center on the grid so the whole 3-zone block sits centered
       inside the row when content < container. */
    grid-template-columns:
      var(--tk-header-side-col-min, 1fr)
      auto
      var(--tk-header-side-col-min, 1fr);
    justify-content: center;
    grid-template-areas:
      "logo nav actions"
      "city search actions"
      ".    categories ."
      ;
    column-gap: 18px;
    row-gap: 0;
    align-items: center;
  }
  .tk-logo-shell {
    /* Founder LIVE EDIT 2026-04-30 (single-global-menu pass — logo
       Y-axis bug fix): merge the desktop brand vertical-align (existing
       baseline alignment) with the live offset-x / offset-y vars set by
       the Founder Admin sliders. The base rule at line 372 wrote
       transform: translate(offset-x, offset-y) but THIS media-query
       rule overrode it with translateY(brand-vertical-align), which
       erased the Founder offset entirely. Combining both into one
       transform expression preserves the baseline align AND honors the
       Founder slider values live.
       Founder LIVE EDIT 2026-05-01 (TRUE CENTER LOCK + LOCATION
       PILL CORRECTION): justify-self stays "center" so the logo
       sits horizontally centered in the left rail and the
       Vancouver pill sits centered directly UNDER the title (per
       Founder's "centre the location back with the title as it was
       before"). The symmetric 1fr-auto-1fr column grid above
       guarantees the center-stack stays at viewport center
       regardless of the left rail's content. */
    grid-area: logo;
    min-width: 0;
    width: min(100%, var(--tk-desktop-brand-block-width));
    /* Founder HARD CORRECTION 2026-05-03 — RIGHT-ALIGN brand to the
       column's right edge so brand.R == city.R. Both elements share
       the same column; if either is `center`, they end at different
       x because their widths differ — the user perceives the
       Vancouver-BC pill as "63px from search" while the brand word
       reads as "26px from search". With both right-aligned, every
       row-end visible to the eye lands on the same x coordinate. */
    justify-self: end;
    /* Founder HARD CORRECTION 2026-05-03 — equalizer-X composed
       with the existing offset-X slider so SEARCH→brand vs
       SEARCH→actions visible gaps stay equal at every viewport. */
    transform: translate(
      calc(var(--tk-desktop-brand-logo-offset-x, 0px) + var(--tk-header-equalize-shift-x, 0px)),
      calc(var(--tk-desktop-brand-vertical-align) + var(--tk-desktop-brand-logo-offset-y, 0px))
    ) scale(var(--tk-desktop-brand-auto-scale, 1));
  }
  .tk-logo {
    justify-content: center;
    width: 100%;
    gap: var(--tk-desktop-brand-logo-gap);
  }
  .tk-logo-mark {
    width: var(--tk-desktop-brand-mark-size);
    height: var(--tk-desktop-brand-mark-size);
  }
  .tk-logo-word {
    /* Founder HARD CORRECTION 2026-05-03 (REVERTED 2026-05-03):
       removed the clamp() — it made the JSON wordSize the CEILING,
       not the actual size, so dragging the slider to 60px did
       nothing visible because 1.6vw at 1440 = 23px won the clamp.
       Now the slider/JSON value IS the rendered font-size, full
       stop. Admin owns it; no responsive ceiling/floor formula. */
    font-size: var(--tk-desktop-brand-word-size, 48px);
    line-height: 1;
    align-self: center;
    white-space: nowrap;
  }
		  .tk-city {
		    /* Founder LIVE EDIT 2026-05-01 (LOCATION PILL — LOCK TO
		       TITLE+LOGO): translateY contains the logo's vertical-
		       align + the location's own offset so the pill is anchored
		       directly under the title.
		       Founder LIVE EDIT 2026-05-01 (BRAND BLOCK SNAP FIX): the
		       Brand Block Geometry sliders write to
		       --tk-desktop-brand-logo-offset-x and -y at :root level.
		       Previously only .tk-logo-shell consumed those vars; now
		       .tk-city consumes them too (additive on top of its own
		       location-offset) so the logo + title + location pill
		       all move TOGETHER as one BrandBlock when the offset
		       sliders or the snap buttons change. Founder's exact rule:
		       "Do not position logo, title, and location independently.
		       All movement applies to BrandBlock."
		       Founder HARD CORRECTION 2026-05-03 — RIGHT-ALIGN to
		       column right edge so city.R == brand.R. Otherwise the
		       Vancouver-BC pill ends ~37px short of the brand word
		       (because city is narrower) and the user reads the
		       row-2 gap to search as 63px while the row-1 gap reads
		       as 26px. justify-self: end pins both to the same x. */
		    grid-area: city;
		    justify-self: end;
		    /* Founder HARD CORRECTION 2026-05-03 — equalizer-X
		       moves city pill in lockstep with brand-shell so the
		       BrandBlock stays vertically aligned as the gap
		       equalizer shifts. */
		    transform: translate(
		      calc(var(--tk-desktop-brand-logo-offset-x, 0px) + var(--tk-header-equalize-shift-x, 0px)),
		      calc(
		        var(--tk-desktop-brand-vertical-align)
		        + var(--tk-desktop-location-offset)
		        + var(--tk-desktop-brand-logo-offset-y, 0px)
		      )
		    ) scale(var(--tk-desktop-computed-location-scale, var(--tk-desktop-location-scale)));
		    transform-origin: center top;
		    align-self: start;
		  }
		  .tk-city-btn {
		    height: var(--desktop-location-pill-height);
		    min-height: var(--desktop-location-pill-height);
		    padding: 0 var(--desktop-location-pill-padding-x);
		    gap: var(--desktop-location-pill-gap);
		    font-size: var(--desktop-location-pill-font-size);
		    line-height: 1;
		    box-shadow: none;
		    background: rgba(255, 255, 255, 0.68);
		  }
		  .tk-city-btn .tk-icon-sm {
		    width: var(--desktop-location-pill-icon-size);
		    height: var(--desktop-location-pill-icon-size);
		  }
  .tk-logo-tag { display: none !important; }
  .tk-main-menu {
    /* Founder LIVE EDIT 2026-05-01 (TRUE CENTER LOCK): nav lives in
       the auto-sized center column; justify-self: center keeps the
       individual link list horizontally centered within that column
       so the visual center stays at viewport center even when the
       nav has more or fewer links than the search bar / category bar
       widths. */
    grid-area: nav;
    display: flex !important;
    justify-content: center;
    align-items: center;
    align-self: end;
    justify-self: center;
    max-width: min(760px, 100%);
  }
  .tk-search {
    /* Founder LIVE EDIT 2026-05-01 (TRUE CENTER LOCK): center column
       is auto-sized so the search bar's width is the natural width
       of this center column. min-width / max-width clamp the search
       so it doesn't grow with viewport — keeping the center column
       a fixed visual size that does not drift when logo/actions
       resize. */
    grid-area: search;
    width: min(760px, 100%);
    min-width: min(420px, 100%);
    max-width: 760px;
    justify-self: center;
    align-self: start;
    transform: translateY(var(--tk-desktop-search-offset-y, 0px));
  }
  .tk-header-actions {
    /* Founder LIVE EDIT 2026-05-01 (TRUE CENTER LOCK): justify-self
       end keeps the action buttons (cart, account, sign-up, etc.)
       on the right edge of the viewport. The right column is
       minmax(brand-block, 1fr) symmetric with the left column, so
       even when actions content is wider/narrower than logo+city,
       the centered nav/search/categories never shift — the auto
       center column stays exactly at viewport center.
       Founder LIVE EDIT 2026-05-01 (RIGHT ICON SNAP CONTROLS): the
       translateY consumes --tk-desktop-right-icons-offset-y so the
       Founder admin "Snap right icons vertical" / "Snap right
       icons to search bar Y" buttons can move the entire cluster
       (cart, activity, heart, account, login, logout) as one group.
       Cart badge stays attached because it's a child of the cart
       button inside .tk-header-actions — the transform applies
       once at the wrapper level. */
    grid-area: actions;
    justify-self: end;
    align-self: center;
    /* Founder HARD CORRECTION 2026-05-03 — equalizer-X: the
       JS controller wireHeaderInnerGapEqualizer (run.js)
       measures the visible gap between SEARCH BAR and brand
       block vs SEARCH BAR and right-icon cluster, computes a
       shift that makes both equal, and writes
       --tk-header-equalize-shift-x onto .tk-logo-shell,
       .tk-city, AND .tk-header-actions. The transform here
       composes that shift with the existing right-icons-offset-y
       slider so the cluster slides horizontally without
       breaking the vertical snap. */
    transform: translate(
      var(--tk-header-equalize-shift-x, 0px),
      var(--tk-desktop-right-icons-offset-y, 0px)
    );
  }
  .tk-mobile-favorites-action {
    display: none !important;
  }
	  .tk-header-actions [data-tk-notifications-toggle] { order: 1; }
	  .tk-header-actions .tk-favorites-action { order: 2; }
  .tk-header-actions [data-tk-cart-toggle] { order: 3; }
  .tk-header-actions [data-tk-login] { order: 4; }
  .tk-header-actions [data-tk-account] { order: 4; }
  .tk-header-actions [data-tk-signup] { order: 5; }
  .tk-header-actions [data-tk-logout] { order: 5; }
  .tk-auth-signup {
    min-width: auto;
    width: auto;
    padding: 0 14px;
  }
  .tk-categories-shell {
    /* Founder live edit 2026-04-29: category nav is attached under the
       search bar and sized by header.categoryMenuLayout JSON. The newest
       correction removes rounded menu ends and keeps only left/right fades;
       all labels from All through ACCESSORIES must fit before 90% width wins.
       Founder LIVE EDIT BLOCK 2026-04-30 (item 5 — overlap-bottom): negative
       margin-bottom (driven by --tk-desktop-category-overlap-bottom from
       categoryMenuLayout.desktopGreenBarOverlapBottom JSON) pulls the green
       rail's bottom past the cream panel so a few less px of white show
       below the green. */
    grid-area: categories;
    position: relative;
	    width: var(--tk-category-menu-desktop-width);
	    max-width: var(--tk-category-menu-desktop-max-width);
	    justify-self: center;
	    margin: var(--tk-category-menu-desktop-gap) auto calc(-1 * var(--tk-desktop-category-overlap-bottom, 0px));
	    padding: 4px calc(var(--tk-category-menu-edge-fade-width) + 4px);
	    background: var(--tk-category-menu-desktop-bg);
	    border: 0;
	    border-radius: 0;
	    box-shadow: none;
    overflow: hidden;
    isolation: isolate;
    transform: translateY(var(--tk-desktop-category-offset-y, 0px));
    /* Founder live edit 2026-04-29: fade the green category rail itself to
       transparency. Do not place light/gray overlay blocks over the edges or
       bottom; the mask is fed by header.categoryMenuLayout JSON variables. */
    -webkit-mask-image:
      linear-gradient(90deg, transparent 0, #000 var(--tk-category-menu-edge-fade-width), #000 calc(100% - var(--tk-category-menu-edge-fade-width)), transparent 100%),
      linear-gradient(180deg, #000 0, #000 calc(100% - var(--tk-category-menu-bottom-fade-height)), transparent 100%);
    -webkit-mask-composite: source-in;
    mask-image:
      linear-gradient(90deg, transparent 0, #000 var(--tk-category-menu-edge-fade-width), #000 calc(100% - var(--tk-category-menu-edge-fade-width)), transparent 100%),
      linear-gradient(180deg, #000 0, #000 calc(100% - var(--tk-category-menu-bottom-fade-height)), transparent 100%);
    mask-composite: intersect;
  }
  .tk-categories-shell::before,
  .tk-categories-shell::after {
    content: none;
    position: absolute;
    top: 0;
    bottom: 0;
    z-index: 2;
    width: var(--tk-category-menu-edge-fade-width);
    pointer-events: none;
  }
  .tk-categories-shell::before {
    left: 0;
    background: linear-gradient(90deg, var(--tk-category-menu-edge-fade-color), transparent);
  }
  .tk-categories-shell::after {
    right: 0;
    background: linear-gradient(270deg, var(--tk-category-menu-edge-fade-color), transparent);
  }
  .tk-categories {
    width: 100%;
    max-width: none;
    margin: 0;
    padding: 0;
    background: transparent;
    border: 0;
    box-shadow: none;
    gap: var(--desktop-category-item-gap);
    justify-content: flex-start;
    scroll-padding-left: 0;
    overflow-x: auto;
    overflow-y: hidden;
  }
  .tk-cat {
    position: relative;
    z-index: 1;
    flex: 0 0 auto;
    min-width: max-content;
    border: 0;
    border-radius: 0;
    background: transparent;
    color: rgba(255, 255, 255, 0.86);
    padding: var(--desktop-category-item-padding-y) var(--desktop-category-item-padding-x);
    font-size: var(--desktop-category-font-size);
    line-height: 1.12;
    font-weight: 900;
    letter-spacing: 0.015em;
  }
  .tk-cat::before,
  .tk-main-menu-link::before {
    content: "";
    position: absolute;
    inset: var(--tk-category-active-glow-inset);
    z-index: -1;
    border-radius: 999px;
    background: var(--tk-category-active-glow-bg);
    opacity: 0;
    pointer-events: none;
    transition: opacity .16s ease;
  }
  .tk-cat:hover {
    color: #fff;
    background: transparent;
  }
  .tk-cat[data-active="true"] {
    background: transparent;
    color: #fff;
  }
  .tk-cat[data-active="true"]::before,
  .tk-cat:hover::before {
    opacity: 1;
  }
  .tk-main-menu-link {
    position: relative;
  }
  .tk-main-menu-link[data-active="true"] {
    color: var(--tk-leaf-deep);
    background: transparent;
    box-shadow: none;
    border-radius: 0;
  }
  .tk-main-menu-link[data-active="true"]::before,
  .tk-main-menu-link:hover::before {
    opacity: 1;
    background: radial-gradient(circle at 50% 50%, color-mix(in srgb, var(--tk-leaf) 24%, transparent), color-mix(in srgb, var(--tk-leaf) 12%, transparent) 45%, transparent 72%);
  }
}
@media (min-width: 981px) and (max-width: 1180px) {
  /* Founder HARD CORRECTION 2026-05-03 — founder Z/X/Y/A/B header
     pass: this 981–1180 break also has to keep the center column
     mathematically centered. Was a 3-track template with a fixed
     left + 1fr + auto layout that drifted center +53px right at
     1100vw. Now mirrors the 1180+ rule: side cols share
     --tk-header-side-col-min so left/right zones are equal width
     and the center auto column sits at row center. */
  .tk-header-row {
    grid-template-columns:
      var(--tk-header-side-col-min, 1fr)
      auto
      var(--tk-header-side-col-min, 1fr);
    justify-content: center;
    column-gap: 12px;
  }
  .tk-main-menu {
    gap: 4px;
  }
  .tk-main-menu-link {
    font-size: 12px;
    padding-inline: 3px;
  }
  .tk-header-actions {
    gap: 6px;
  }
  .tk-search {
    min-width: min(340px, 100%);
  }
}
.tk-icon-action,
.tk-auth-link {
  min-width: 38px;
  min-height: 38px;
  border: 0;
  background: transparent;
  color: var(--tk-ink-soft);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  cursor: pointer;
  text-decoration: none;
  font: inherit;
  font-size: 13px;
  font-weight: 800;
  position: relative;
}
.tk-icon-action[hidden],
.tk-auth-link[hidden] {
  display: none !important;
}
.tk-icon-action:hover,
.tk-auth-link:hover { color: var(--tk-leaf-deep); }
.tk-mobile-favorites-action {
  display: none !important;
}
.tk-auth-signup {
  min-height: 36px;
  padding: 0 14px;
  border-radius: 999px;
  background: var(--tk-leaf-soft);
  color: var(--tk-leaf-deep);
}
.tk-header-actions .tk-account-link {
  width: 46px;
  height: 46px;
  min-width: 46px;
  min-height: 46px;
  color: var(--tk-leaf-deep);
}
.tk-notification-count {
  position: absolute;
  top: 1px;
  right: 1px;
  min-width: 15px;
  height: 15px;
  border-radius: 999px;
  display: inline-grid;
  place-items: center;
  background: var(--tk-warm);
  color: var(--tk-paper);
  font-size: 9px;
  font-weight: 900;
}
.tk-notifications-popover {
  position: absolute;
  right: var(--tk-notifications-right, clamp(16px, 3vw, 28px));
  top: calc(100% + var(--tk-notifications-top-offset, 6px));
  z-index: 45;
  width: var(--tk-notifications-width, min(320px, calc(100vw - 28px)));
  padding: 14px;
  border: 1px solid var(--tk-line);
  border-radius: 18px;
  background: var(--tk-paper);
  box-shadow: 0 18px 44px rgba(20,20,18,0.18);
}
.tk-notifications-popover[hidden] { display: none; }
.tk-notifications-popover h2,
.tk-notification-item h3,
.tk-notification-item p { margin: 0; }
.tk-notification-item {
  display: grid;
  gap: 3px;
  padding-top: 10px;
  margin-top: 10px;
  border-top: 1px solid var(--tk-line);
}
.tk-notification-item h3 { font-size: 14px; }
.tk-notification-item p { color: var(--tk-muted); font-size: 12px; }
.tk-notification-friends {
  display: grid;
  gap: 8px;
  padding-top: 12px;
  margin-top: 12px;
  border-top: 1px solid var(--tk-line);
}
.tk-notification-friends h3,
.tk-friends-section h4 { margin: 0; color: var(--tk-leaf-deep); }
.tk-friends-section { display: grid; gap: 6px; }
.tk-friend-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  font-size: 12px;
}
.tk-friend-row button {
  border: 0;
  border-radius: 999px;
  background: var(--tk-leaf-deep);
  color: var(--tk-paper);
  padding: 5px 9px;
  font: inherit;
  font-size: 11px;
  font-weight: 900;
}
.tk-friend-row em { font-style: normal; color: var(--tk-muted); }
/* Founder HARD CORRECTION 2026-05-03 — small remove control on
   accepted-friend rows so dead/inactive friends can actually be
   deleted. Sized small (18×18) and muted so it doesn't dominate
   the row. Hover/active states reuse brand tokens. */
.tk-friend-remove {
  width: 18px;
  height: 18px;
  min-width: 18px;
  border: 0;
  border-radius: 999px;
  background: color-mix(in srgb, var(--tk-leaf-deep) 8%, transparent);
  color: var(--tk-muted);
  font-size: 12px;
  font-weight: 700;
  line-height: 1;
  padding: 0;
  cursor: pointer;
  display: inline-grid;
  place-items: center;
}
.tk-friend-remove:hover {
  background: color-mix(in srgb, var(--tk-warm) 22%, transparent);
  color: var(--tk-warm);
}
.tk-friend-remove:disabled { opacity: 0.4; cursor: wait; }
.tk-friend-row .tk-toke-bucks-positive {
  /* Founder LIVE EDIT BLOCK 2026-05-01 (referral notification +Toke
     Bucks must be theme green): switched from --tk-status-online
     (which can resolve to a different green family on dark mode) to
     --tk-leaf-deep, the canonical platform dark green token. The
     positive-amount text reads consistently green across themes. */
  color: var(--tk-leaf-deep);
  font-weight: 900;
}
.tk-business-referral {
  display: grid;
  gap: 12px;
  padding: 12px;
  border: 1px solid color-mix(in srgb, var(--tk-leaf) 18%, transparent);
  border-radius: 18px;
  background:
    radial-gradient(circle at 100% 0%, rgba(161, 215, 118, 0.2), transparent 34%),
    rgba(242, 247, 235, 0.72);
}
.tk-business-referral-compact {
  padding: 10px;
  gap: 9px;
}
.tk-business-referral-head {
  display: grid;
  gap: 3px;
}
.tk-business-referral-head h3,
.tk-business-referral-head p {
  margin: 0;
}
.tk-business-referral-head h3 {
  color: var(--tk-leaf-deep);
  font-size: 15px;
}
.tk-business-referral-head p,
.tk-business-referral-instruction,
.tk-business-referral-status {
  color: var(--tk-ink-soft);
  font-size: 12px;
}
.tk-business-referral-offers {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}
.tk-business-referral-offers article {
  display: grid;
  gap: 3px;
  padding: 10px;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.7);
  border: 1px solid var(--tk-line);
}
.tk-business-referral-offers strong {
  color: var(--tk-leaf-deep);
}
.tk-business-referral-offers span {
  color: var(--tk-muted);
  font-size: 12px;
}
.tk-business-referral-search {
  display: grid;
  gap: 5px;
  color: var(--tk-leaf-deep);
  font-size: 12px;
  font-weight: 800;
}
.tk-business-referral-search input {
  width: 100%;
  border: 1px solid var(--tk-line);
  border-radius: 999px;
  padding: 9px 12px;
  background: var(--tk-paper);
  color: var(--tk-ink);
  font: inherit;
}
.tk-business-referral-store-list {
  display: grid;
  gap: 7px;
  max-height: 210px;
  overflow: auto;
  padding-right: 2px;
}
.tk-business-referral-store-list button {
  width: 100%;
  display: grid;
  grid-template-columns: 34px 1fr;
  align-items: center;
  gap: 10px;
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 14%, transparent);
  border-radius: 14px;
  padding: 7px 9px;
  background: rgba(255, 255, 255, 0.76);
  color: var(--tk-ink);
  text-align: left;
  cursor: pointer;
}
.tk-business-referral-store-list button[data-active="true"] {
  border-color: var(--tk-leaf);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--tk-leaf) 13%, transparent);
}
.tk-business-referral-logo {
  width: 34px;
  height: 34px;
  border-radius: 999px;
  display: grid;
  place-items: center;
  overflow: hidden;
  background: var(--tk-leaf-deep);
  color: var(--tk-paper);
  font-weight: 950;
  font-size: 11px;
  letter-spacing: 0.08em;
}
.tk-business-referral-logo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.tk-business-referral-store-list strong,
.tk-business-referral-store-list em {
  display: block;
}
.tk-business-referral-store-list em {
  color: var(--tk-muted);
  font-style: normal;
  font-size: 11px;
}
.tk-friends-online-button {
  position: fixed;
  left: 16px;
  bottom: 14px;
  z-index: 42;
  width: 30px;
  height: 30px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--tk-leaf-deep);
  display: grid;
  place-items: center;
  cursor: pointer;
  box-shadow: none;
}
.tk-friends-online-button > span {
  width: 14px;
  height: 14px;
  border-radius: 999px;
  background: var(--tk-status-offline);
  box-shadow: 0 0 0 5px var(--tk-status-glow-offline), 0 0 14px var(--tk-status-glow-offline);
}
.tk-friends-online-button[data-state="online"] > span {
  background: var(--tk-status-online);
  box-shadow: 0 0 0 5px var(--tk-status-glow-online), 0 0 16px var(--tk-status-glow-online);
  animation: tkFriendPulse 1.4s ease-in-out infinite;
}
.tk-friends-online-button[data-state="idle"] > span {
  background: var(--tk-status-idle);
  box-shadow: 0 0 0 5px var(--tk-status-glow-idle), 0 0 16px var(--tk-status-glow-idle);
}
.tk-friends-online-button strong {
  position: absolute;
  top: -8px;
  right: -10px;
  min-width: 18px;
  height: 18px;
  border-radius: 999px;
  background: var(--tk-leaf-deep);
  color: var(--tk-paper);
  font-size: 10px;
  display: grid;
  place-items: center;
}
@keyframes tkFriendPulse {
  0%, 100% { box-shadow: 0 0 0 4px var(--tk-status-glow-online), 0 0 14px var(--tk-status-glow-online); }
  50% { box-shadow: 0 0 0 8px color-mix(in srgb, var(--tk-leaf) 0%, transparent), 0 0 18px var(--tk-status-glow-online); }
}

.tk-homepage-rows {
  display: grid;
  gap: 28px;
}
.tk-row-title-wrap {
  display: grid;
  gap: 2px;
}
.tk-row-group {
  color: var(--tk-leaf);
  font-size: 10px;
  font-weight: 900;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.tk-row-head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
}
.tk-row-view {
  justify-self: end;
  color: var(--tk-leaf-deep);
  text-decoration: none;
  font-size: 12px;
  font-weight: 900;
}
.tk-card-stars-meter {
  display: inline-flex;
  gap: 1px;
}
.tk-star {
  position: relative;
  display: inline-block;
  color: var(--tk-line-strong);
  font-size: 13px;
  line-height: 1;
}
.tk-star::before {
  content: "★";
  position: absolute;
  inset: 0;
  width: var(--tk-star-fill, 0%);
  overflow: hidden;
  color: var(--tk-warm);
}

.tk-location-picker {
  /* Founder LIVE EDIT 2026-05-01 (FIRST VISIT STACK ORDER FIX —
     CITY PICKER = LOCATION PICKER TIER): when the user denies
     navigator.geolocation (or the existing decision expires) the
     "What city?" modal pops up. Founder flagged on real device:
     "I could see the homepage menu, but it's supposed to be
     behind it." Bumped z-index from 86 → 9999 (Founder's "Location
     Picker" tier — topmost) so the menu (z 4000), privacy banner
     (z 5000), and any popups (z 8500) all sit behind it. The
     body.tk-location-open class is already set by demo.js when
     this picker mounts; the body.tk-location-open .tk-header /
     .tk-legal-banner rule below uses it to hide the menu+banner
     while the picker is active (per Founder's modal-isolation
     rule). */
  position: fixed;
  inset: 0;
  z-index: 9999;
  display: grid;
  place-items: center;
  padding: 18px;
  background: color-mix(in srgb, var(--tk-paper) 72%, transparent);
  backdrop-filter: blur(12px);
  overflow: hidden;
  touch-action: none;
}
.tk-location-picker[hidden] { display: none; }
body.tk-location-open {
  overflow: hidden;
  overscroll-behavior: none;
}
.tk-location-card {
  width: min(560px, 100%);
  max-height: min(90dvh, calc(var(--visual-vh, 1vh) * 90));
  display: grid;
  grid-template-rows: auto auto auto auto minmax(0, 1fr) auto;
  gap: 14px;
  padding: 22px;
  border-radius: 24px;
  background: var(--tk-paper);
  border: 1px solid var(--tk-line);
  box-shadow: 0 22px 70px rgba(20,20,18,0.2);
  overflow: hidden;
  touch-action: pan-y;
}
.tk-location-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 14px;
}
.tk-location-head h2,
.tk-location-head p { margin: 0; }
.tk-location-head p:last-child { color: var(--tk-muted); font-size: 13px; }
.tk-location-close,
.tk-cart-close {
  border: 0;
  background: transparent;
  color: var(--tk-muted);
  cursor: pointer;
  font-size: 26px;
  line-height: 1;
}
.tk-location-current {
  display: inline-flex;
  width: fit-content;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-radius: 999px;
  background: var(--tk-leaf-soft);
  color: var(--tk-leaf-deep);
}
.tk-location-field {
  display: grid;
  gap: 5px;
  color: var(--tk-ink-soft);
  font-size: 12px;
  font-weight: 800;
}
.tk-location-field input,
.tk-location-field select {
  width: 100%;
  border: 1px solid var(--tk-line);
  border-radius: 14px;
  padding: 11px 12px;
  background: var(--tk-bg);
  color: var(--tk-ink);
  font: inherit;
}
.tk-location-cities {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  max-height: min(280px, 38svh);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  touch-action: pan-y;
  padding-right: 4px;
}
.tk-location-city {
  border: 1px solid var(--tk-line);
  background: var(--tk-paper);
  color: var(--tk-ink-soft);
  border-radius: 999px;
  padding: 7px 11px;
  cursor: pointer;
  font: inherit;
  font-size: 13px;
}
.tk-location-city-group {
  margin: 4px 0 0;
  color: var(--tk-muted);
  font-size: 10px;
  font-weight: 950;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}
.tk-location-city[data-active="true"] {
  background: var(--tk-leaf);
  border-color: var(--tk-leaf);
  color: var(--tk-paper);
}
/* Founder LIVE EDIT 2026-05-01 (mobile Allow Location feedback):
   the status pill renders inside the picker when geolocation is
   denied/unavailable so the user sees that something happened
   when they tap Allow Location. Without this they thought the
   button "doesn't re-popup the location thing" because there was
   zero visual response after the browser silently rejected the
   re-prompt. */
.tk-location-status {
  margin: 8px 4px 0;
  padding: 10px 12px;
  border-radius: 12px;
  background: color-mix(in srgb, var(--tk-leaf) 12%, transparent);
  color: var(--tk-leaf-deep, var(--tk-leaf-deep, #1f3d2c));
  font-size: 12px;
  line-height: 1.4;
}
.tk-location-status[hidden] { display: none; }
/* Founder LIVE EDIT 2026-05-01 (location icon baseline alignment —
   GLOBAL rule for both desktop and mobile): "move the location
   icon slightly down, so it's level with the word 'Allow' in
   'Allow Location' on desktop AND mobile." Founder's prior fix
   only landed inside the mobile @media block. This global rule
   makes the same -4px vertical-align apply on desktop too. */
.tk-location-allow-arrow,
.tk-location-allow-pin,
.tk-location-allow-nav,
.tk-location-allow-crosshair {
  vertical-align: -4px;
  margin-right: 6px;
}
.tk-location-actions {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}
.tk-location-actions [data-tk-location-save-city] {
  flex: 0 0 auto;
  width: auto;
  min-width: 128px;
  min-height: 42px;
  align-self: center;
  padding-block: 10px;
  line-height: 1.1;
}

.tk-cart-scrim {
  position: fixed;
  inset: 0;
  z-index: 70;
  background: rgba(20,20,18,0.18);
}
.tk-cart-scrim[hidden] { display: none; }
.tk-cart-drawer {
  position: fixed;
  top: 0;
  right: 0;
  z-index: 4500;
  width: min(390px, 100vw);
  height: 100dvh;
  padding: 20px;
  display: grid;
  grid-template-rows: auto 1fr auto auto auto;
  gap: 16px;
  background: var(--tk-paper);
  border-left: 1px solid var(--tk-line);
  box-shadow: -24px 0 70px rgba(20,20,18,0.18);
  transform: translateX(104%);
  transition: transform .22s ease;
}
body.tk-cart-open .tk-cart-drawer { transform: translateX(0); }
.tk-cart-scrim {
  pointer-events: none;
  background: transparent;
}
/* Founder LIVE EDIT 2026-05-01: desktop cart PUSHES the container instead of
   overlaying. The cart drawer reserves --tk-cart-desktop-width on the right;
   .tk-header and .tk-main shift left by exactly that width. Cart z-index is
   above the menu (4500 > 4000) so the drawer stays visible. */
:root {
  --tk-cart-desktop-width: min(390px, 32vw);
}
@media (min-width: 1024px) {
  body.tk-cart-open .tk-header,
  body.tk-cart-open .tk-main {
    transform: translateX(calc(-1 * var(--tk-cart-desktop-width)));
    transition: transform .22s ease;
  }
}
.tk-cart-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.tk-cart-head h2 { margin: 0; }
.tk-cart-items {
  display: grid;
  align-content: start;
  gap: 10px;
  overflow: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-y;
}
.tk-cart-item-swipe {
  position: relative;
  overflow: hidden;
  min-height: 58px;
  background: var(--tk-paper);
  border-bottom: 1px solid var(--tk-line);
}
.tk-cart-delete {
  position: absolute;
  top: 8px;
  right: 0;
  bottom: 8px;
  width: 92px;
  border: 0;
  border-radius: 14px;
  background: #8f2f25;
  color: #fffaf4;
  font: inherit;
  font-size: 12px;
  font-weight: 900;
}
.tk-cart-item {
  display: flex;
  justify-content: space-between;
  gap: 14px;
  padding: 12px 0;
  border-bottom: 0;
  background: var(--tk-paper);
  position: relative;
  z-index: 1;
  will-change: transform;
}
.tk-cart-item div { display: grid; gap: 2px; }
.tk-cart-item span,
.tk-cart-hint { color: var(--tk-muted); font-size: 12px; }
.tk-cart-summary {
  display: grid;
  gap: 8px;
  padding-top: 10px;
  border-top: 1px solid var(--tk-line);
}
.tk-cart-summary div {
  display: flex;
  justify-content: space-between;
  gap: 10px;
}
.tk-cart-buttons {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
@media (max-width: 1180px) {
  .tk-cart-buttons {
    grid-template-columns: 1fr;
  }
}

.tk-favorites-page {
  display: grid;
  gap: 18px;
}
.tk-favorites-page[hidden] { display: none; }
.tk-favorites-head {
  display: grid;
  gap: 5px;
  text-align: center;
  max-width: 700px;
  margin: 0 auto;
}
.tk-favorites-head h2,
.tk-favorites-head p { margin: 0; }
.tk-favorites-head small { color: var(--tk-muted); }
.tk-favorites-rows {
  display: grid;
  gap: 18px;
}
.tk-favorites-row {
  margin: 0;
}
.tk-favorites-track {
  grid-auto-columns: minmax(190px, 230px);
}
.tk-favorites-empty-slot {
  opacity: 0.78;
  pointer-events: none;
}
.tk-favorites-empty-slot .tk-card-art {
  background:
    radial-gradient(circle at 50% 44%, color-mix(in srgb, var(--tk-leaf) 16%, transparent), transparent 42%),
    linear-gradient(135deg, color-mix(in srgb, var(--tk-leaf-deep) 8%, transparent), rgba(216, 143, 60, 0.12));
}

body.tk-favorites-route [data-tk-order] {
  display: none;
}
body.tk-favorites-route .tk-homepage-rows,
body.tk-favorites-route .tk-homepage-rows .tk-row,
body.tk-favorites-route .tk-footer {
  display: none !important;
}

.tk-product-page,
.tk-store-page,
.tk-account-page,
.tk-settings-page {
  display: grid;
  gap: 18px;
}
.tk-product-page[hidden],
.tk-store-page[hidden],
.tk-account-page[hidden],
.tk-settings-page[hidden] { display: none; }
.tk-detail-shell {
  /* Founder missed-items pass 2026-04-30 (item 5): pages should sit directly on
     the site background — no large white-panel container around the whole
     page. Individual cards inside still get their own surfaces. The previous
     white shell with rounded corners is removed; layout (gap/grid) is
     preserved so children continue to space cleanly. */
  display: grid;
  gap: 18px;
  background: transparent;
  border: 0;
  border-radius: 0;
  padding: 0;
  box-shadow: none;
}
.tk-account-shell {
  background: var(--tk-account-shell-background, transparent);
  border: var(--tk-account-shell-border, 0);
  border-radius: var(--tk-account-shell-radius, 0);
  padding: var(--tk-account-shell-padding, 0);
  box-shadow: var(--tk-account-shell-shadow, none);
  width: min(100%, var(--tk-account-shell-max-width, none));
  max-width: var(--tk-account-shell-max-width, none);
  margin-inline: var(--tk-account-shell-margin-inline, 0);
}
@media (max-width: 720px) {
  .tk-account-shell {
    width: min(100%, var(--tk-account-shell-max-width-mobile, 100%));
    max-width: var(--tk-account-shell-max-width-mobile, 100%);
    margin-inline: auto;
  }
}
.tk-account-signedout-prompt {
  display: grid;
  gap: 12px;
  max-width: 620px;
  padding: clamp(18px, 3vw, 28px);
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 10%, transparent);
  border-radius: 20px;
  background:
    radial-gradient(circle at 92% 8%, color-mix(in srgb, var(--tk-leaf) 12%, transparent), transparent 32%),
    rgba(255,255,255,0.68);
}
.tk-account-signedout-prompt h2,
.tk-account-signedout-prompt p,
.tk-account-signedout-prompt small {
  margin: 0;
}
.tk-account-signedout-prompt h2 {
  color: var(--tk-leaf-deep);
  font-size: clamp(28px, 5vw, 44px);
  line-height: 0.96;
  letter-spacing: -0.06em;
}
.tk-account-signedout-prompt p,
.tk-account-signedout-prompt small {
  color: var(--tk-ink-soft);
  line-height: 1.45;
}
.tk-account-signin-cta {
  justify-self: start;
  width: auto;
  min-width: min(100%, 220px);
}
.tk-product-hero {
  display: grid;
  grid-template-columns: minmax(320px, 0.95fr) minmax(280px, 1.05fr);
  gap: clamp(18px, 4vw, 42px);
  align-items: start;
}
.tk-product-layout-shell {
  display: grid;
  gap: clamp(22px, 4vw, 42px);
}
.tk-product-sketch-grid {
  display: grid;
  grid-template-columns: minmax(340px, 0.92fr) minmax(320px, 1.08fr);
  gap: clamp(22px, 4.5vw, 56px);
  align-items: start;
}
.tk-product-left-rail,
.tk-product-right-rail {
  display: grid;
  gap: 16px;
}
.tk-product-right-rail {
  align-content: start;
  padding-top: clamp(6px, 1vw, 14px);
}
.tk-product-right-rail h1 {
  margin: 0;
  color: var(--tk-leaf-deep);
  font-size: clamp(42px, 6vw, 74px);
  line-height: 0.88;
  letter-spacing: -0.07em;
  max-width: 760px;
}
.tk-product-pill-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.tk-product-pill {
  display: inline-flex;
  align-items: center;
  min-height: 30px;
  padding: 6px 11px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 10%, transparent);
  background: rgba(255,255,255,0.72);
  color: var(--tk-leaf-deep);
  font-size: 12px;
  font-weight: 900;
  letter-spacing: .02em;
}
.tk-product-pill-visual {
  background:
    radial-gradient(circle at 24% 20%, rgba(255,255,255,0.9), transparent 30%),
    linear-gradient(135deg, color-mix(in srgb, var(--tk-leaf) 16%, transparent), rgba(216,143,60,0.12));
}
/* Founder LIVE EDIT 2026-05-01: article/guide card titles use website green. */
.tk-card[data-card-type="article"] .tk-card-name,
.tk-card[data-card-type="guide"] .tk-card-name,
.tk-map-article-copy strong {
  color: var(--tk-leaf-deep);
}
.tk-map-article-card .tk-map-article-copy strong { color: var(--tk-leaf); }
/* Founder LIVE EDIT 2026-05-01: product card "fact" line uses green theme. */
/* Founder HARD CORRECTION 2026-05-03 (rev 4) — fact line matches
   the hidden .tk-card-meta-city EXACTLY: 12px, muted, regular
   weight, regular letter-spacing, regular line-height. Founder
   rule: "FONT AND FONTSIZE AND FONTWEIGHT TOO!!!". */
.tk-card-fact {
  display: block;
  color: var(--tk-muted);
  font-size: 12px;
  font-weight: inherit;
  font-family: inherit;
  letter-spacing: normal;
  line-height: 1.18;
  margin-top: 2px;
}
@media (max-width: 720px) {
  .tk-card-fact {
    font-size: 12px;
  }
}
/* Founder LIVE EDIT 2026-05-01: stores use compact ★ #.# rating; products
   keep the five-star meter on its own row below the price. */
.tk-card-stars-compact {
  font-size: 12px;
  font-weight: 800;
  color: var(--tk-warm, #d68f3c);
  letter-spacing: 0.02em;
  white-space: nowrap;
}
/* Founder HARD CORRECTION 2026-05-03 — founder rule: "I STILL SEE
   SOME MOBILE STARS AND AVG TEXT ON DIFF LINES. MAKE SURE IT
   ALWAYS STAYS SAME LINE". Override the prior wrap to nowrap on
   every viewport so [stars][AVG] never breaks. The price font is
   also pinned to match the star's compact size (12px / weight
   800) so neither pushes the other to a new line via differing
   line-heights. */
.tk-card-row {
  flex-wrap: nowrap !important;
  gap: 4px 8px;
  justify-content: center;
  white-space: nowrap;
}
.tk-card-row .tk-card-price {
  font-size: 12px;
  font-weight: 800;
  white-space: nowrap;
}
.tk-card-row .tk-card-stars-compact {
  white-space: nowrap;
}
/* Founder LIVE EDIT 2026-05-01 (pass 51 — center stars on every viewport,
   and place them inline with the avg. price). The 5-star meter for products
   now sits on the same .tk-card-row as the price; the row's centered flex
   layout keeps the [stars][price] pair balanced under the card image. */
.tk-card-stars.tk-card-stars-meter {
  display: inline-flex;
  gap: 1px;
  margin-top: 0;
  align-items: center;
}
.tk-card-meta-stack {
  display: flex;
  flex-direction: column;
  gap: 1px;
  line-height: 1.18;
}
/* Founder HARD CORRECTION 2026-05-03 — founder rule: "MAKE STORE
   NAME DARK theme color when its under product names". Store
   name shown under a product card title now uses --tk-leaf-deep
   (the brand's dark color) so it reads as the "dark theme"
   sublabel under the regular-theme product title. */
.tk-card-meta-store {
  display: block;
  font-weight: 700;
  color: var(--tk-leaf-deep);
  line-height: 1.18;
}
.tk-card-meta-city {
  display: block;
  color: var(--tk-muted, #7a7e7c);
  font-size: 12px;
  line-height: 1.18;
}
.tk-card-meta-stack .tk-card-fact {
  margin-top: 0;
  line-height: 1.18;
}
/* Founder mobile product detail polish 2026-05-01: type/strain/THC/CBD pill row
   uses neutral gray pills, not green. Mobile re-orders the right-rail content
   so pills > title > details > size > add-to-cart+quantity > description. */
.tk-product-category-pills .tk-product-pill,
.tk-product-pill-cannabinoid {
  background: color-mix(in srgb, var(--tk-leaf-deep) 6%, transparent);
  border-color: color-mix(in srgb, var(--tk-leaf-deep) 16%, transparent);
  color: var(--tk-ink, #2a2f2c);
}
.tk-product-buy-row {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.tk-product-buy-row .tk-product-add-cart {
  flex: 1 1 200px;
  width: auto;
  margin: 0;
}
.tk-product-buy-row .tk-product-quantity {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
}
.tk-product-buy-row .tk-product-quantity-label {
  display: none;
}
.tk-product-buy-row .tk-product-quantity-stepper {
  margin: 0;
}
/* Founder HARD CORRECTION 2026-05-03 — founder rule: "make the
   quantity button have the same color green on the '+' and '-'
   circles in both dark and regular mode". Both inc and dec now
   use --tk-leaf bg + white text, matching shape and color, in
   either theme. The dark-mode override block below leaves these
   alone so they keep the brand green/blue (per host). */
.tk-product-buy-row .tk-product-quantity-stepper button[data-tk-qty-inc],
.tk-product-buy-row .tk-product-quantity-stepper button[data-tk-qty-dec],
.tk-product-quantity-stepper button[data-tk-qty-inc],
.tk-product-quantity-stepper button[data-tk-qty-dec] {
  background: var(--tk-leaf) !important;
  color: #fff !important;
}
@media (max-width: 720px) {
  .tk-product-size-picker button {
    color: var(--tk-leaf-deep);
  }
  .tk-product-size-picker button b {
    color: var(--tk-leaf-deep);
  }
  .tk-product-size-picker button[data-active="true"] b,
  .tk-product-size-picker button[data-active="true"] small {
    color: #fff;
  }
}
.tk-product-pill-group {
  display: grid;
  gap: 7px;
}
.tk-product-pill-label {
  color: var(--tk-muted);
  font-size: 11px;
  font-weight: 900;
  letter-spacing: .16em;
  text-transform: uppercase;
}
.tk-product-attribute-grid {
  /* Founder zero-blocker live edit 2026-04-30 (P2): Effects/Uses/Time of Day
     pill grid uses exactly 3 columns on desktop and 2 on mobile, fed via
     productDetail.attributeGrid.{desktopColumns,mobileColumns} CSS vars. */
  display: grid;
  grid-template-columns: repeat(var(--tk-product-attribute-grid-columns, 3), minmax(0, 1fr));
  gap: var(--tk-product-attribute-grid-gap, 8px);
}
@media (max-width: 720px) {
  .tk-product-attribute-grid {
    grid-template-columns: repeat(var(--tk-product-attribute-grid-mobile-columns, 2), minmax(0, 1fr));
    gap: var(--tk-product-attribute-grid-mobile-gap, 8px);
  }
  /* Founder HARD CORRECTION 2026-05-03 — founder rule (verbatim):
     "mobile: make time of day columns be 2 like uses and effects".
     Was repeat(3, 1fr) (a previous "must be 3 cols" instruction).
     Reinforced as 2 here AND in the media-query at ~line 10435 so
     cascade order can never collapse it back. */
  .tk-product-pill-group[data-attribute-section="timeOfDay"] .tk-product-attribute-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
/* Founder zero-blocker live edit 2026-04-30 (P3): desktop product page must
   place Size and Quantity selectors side-by-side; basis vars come from
   productDetail.desktopSizeQuantityRow. Add to Cart sits below as a wide CTA. */
.tk-product-size-quantity-row[data-tk-size-quantity-side-by-side="true"] {
  display: grid;
  grid-template-columns: var(--tk-product-size-basis, minmax(0, 1.4fr)) var(--tk-product-quantity-basis, minmax(120px, 0.6fr));
  gap: var(--tk-product-size-quantity-row-gap, 12px);
  align-items: end;
}
.tk-product-size-quantity-row .tk-product-quantity {
  align-self: end;
}
.tk-product-add-cart {
  width: 100%;
}
@media (max-width: 720px) {
  .tk-product-size-quantity-row[data-tk-size-quantity-side-by-side="true"] {
    grid-template-columns: 1fr;
    gap: 10px;
  }
}
/* Founder zero-blocker live edit 2026-04-30 (P2/P3): customer images sit
   inside the left rail visually on desktop (under media) and below the
   product description on mobile. Layout swap via grid placement; on mobile
   the third grid item flows after right-rail content (which contains the
   description). */
.tk-product-customer-images-section {
  display: contents;
}
.tk-product-customer-images-section .tk-product-image-row[data-source="customer"] {
  margin-top: 4px;
}
@media (min-width: 981px) {
  .tk-product-sketch-grid {
    grid-template-rows: auto auto;
  }
  .tk-product-customer-images-section {
    display: block;
    grid-column: 1;
    grid-row: 2;
  }
  .tk-product-left-rail {
    grid-column: 1;
    grid-row: 1;
  }
  .tk-product-right-rail {
    grid-column: 2;
    grid-row: 1 / span 2;
  }
}
/* Founder zero-blocker live edit 2026-04-30 (P3): hero top-align removes any
   pre-image whitespace so the visual is the first thing on the product page. */
.tk-product-layout-shell[data-tk-product-hero-top-align="true"] .tk-product-left-rail {
  padding-top: var(--tk-product-hero-desktop-top, 0px);
}
@media (max-width: 980px) {
  .tk-product-layout-shell[data-tk-product-hero-top-align="true"] .tk-product-left-rail {
    padding-top: var(--tk-product-hero-mobile-top, 0px);
  }
}
.tk-product-attribute {
  display: grid;
  grid-template-columns: 34px minmax(0, 1fr) auto;
  align-items: center;
  gap: 9px;
  min-height: 50px;
  padding: 9px 10px;
  border: 0;
  border-radius: 16px;
  background:
    radial-gradient(circle at 18% 18%, rgba(255,255,255,0.74), transparent 34%),
    linear-gradient(135deg, rgba(11, 36, 23, 0.94), rgba(36, 77, 48, 0.9));
  color: var(--tk-paper);
  box-shadow: 0 10px 24px color-mix(in srgb, var(--tk-leaf-deep) 13%, transparent);
}
.tk-product-attribute i {
  position: relative;
  width: 30px;
  height: 30px;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.08);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,0.16), 0 0 18px rgba(127,192,142,0.2);
}
.tk-product-attribute i::before,
.tk-product-attribute i::after {
  content: "";
  position: absolute;
  inset: 8px;
  border: 2px solid rgba(255, 232, 173, 0.9);
  border-radius: 999px;
}
.tk-product-attribute[data-attr-icon="soft-wave"] i::before,
.tk-product-attribute[data-attr-icon="night-arc"] i::before {
  inset: 9px 6px;
  border-width: 0 0 2px;
  border-radius: 0 0 999px 999px;
}
.tk-product-attribute[data-attr-icon="focus-ring"] i::after,
.tk-product-attribute[data-attr-icon="sun-arc"] i::after {
  inset: 12px;
  background: rgba(255,255,255,0.78);
  border: 0;
}
.tk-product-attribute[data-attr-icon="signal-cluster"] i::before {
  inset: 6px 14px 6px 6px;
  border-radius: 999px 0 0 999px;
}
.tk-product-attribute[data-attr-icon="leaf-shield"] i::before {
  inset: 7px 9px;
  border-radius: 65% 0 65% 0;
  transform: rotate(-35deg);
}
.tk-product-attribute strong {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: 13px;
}
.tk-product-attribute em {
  min-width: 22px;
  min-height: 22px;
  display: inline-grid;
  place-items: center;
  border-radius: 999px;
  background: hsl(134 48% calc(28% + (var(--tk-count-strength, 0) * 24%)));
  color: var(--tk-paper);
  font-size: 10px;
  font-style: normal;
  font-weight: 900;
  box-shadow: 0 0 14px rgba(91, 220, 119, calc(0.16 + (var(--tk-count-strength, 0) * 0.22)));
}
.tk-product-media {
  position: relative;
  min-height: 360px;
  border-radius: 26px;
  overflow: hidden;
  background:
    radial-gradient(circle at 50% 38%, rgba(255,255,255,0.12), transparent 32%),
    radial-gradient(circle at 50% 42%, color-mix(in srgb, var(--tk-leaf) 34%, transparent), transparent 54%),
    linear-gradient(145deg, rgba(5,16,11,0.96), rgba(18,48,34,0.94));
}
.tk-product-left-rail .tk-product-media {
  min-height: clamp(390px, 42vw, 560px);
}
.tk-product-media-slot {
  position: absolute;
  inset: 0;
}
.tk-product-official-stack {
  position: absolute;
  top: 18px;
  left: -16px;
  z-index: 6;
  display: grid;
  gap: 9px;
  width: min(96px, 18vw);
}
.tk-product-official-stack button {
  position: relative;
  min-height: 72px;
  border: 1px solid rgba(255,255,255,0.22);
  border-radius: 16px;
  padding: 0;
  background:
    radial-gradient(circle at 66% 28%, rgba(255,255,255,0.42), transparent 26%),
    linear-gradient(145deg, rgba(24,74,45,0.96), rgba(6,22,14,0.94));
  color: transparent;
  cursor: pointer;
  box-shadow: 0 16px 30px rgba(0,0,0,0.18);
  overflow: hidden;
}
.tk-product-official-stack button span {
  position: absolute;
  inset: 12px 16px;
  border-radius: 999px 999px 70% 70%;
  background:
    radial-gradient(circle at 50% 30%, rgba(236,255,229,0.92), transparent 18%),
    radial-gradient(circle at 55% 58%, rgba(100,165,77,0.96), rgba(27,72,35,0.98) 62%, rgba(12,33,19,0.96) 100%);
  filter: drop-shadow(0 10px 14px rgba(0,0,0,0.28));
}
.tk-product-official-stack button[data-active="true"] {
  transform: translateX(8px);
  border-color: rgba(116, 201, 134, 0.9);
}
.tk-favorite-button {
  position: absolute;
  top: 14px;
  right: 14px;
  border: 0;
  border-radius: 999px;
  padding: 9px 12px;
  background: rgba(255,255,255,0.86);
  color: var(--tk-leaf-deep);
  box-shadow: 0 12px 28px color-mix(in srgb, var(--tk-leaf-deep) 14%, transparent);
  cursor: pointer;
}
.tk-media-toggle {
  position: absolute;
  right: 14px;
  bottom: 14px;
  display: inline-flex;
  gap: 4px;
  padding: 4px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--tk-leaf-deep) 82%, transparent);
}
.tk-media-toggle button {
  border: 0;
  border-radius: 999px;
  padding: 7px 11px;
  background: transparent;
  color: rgba(255,255,255,0.72);
  font: inherit;
  cursor: pointer;
}
.tk-media-toggle button[data-active="true"] {
  background: var(--tk-paper);
  color: var(--tk-leaf-deep);
}
.tk-media-toggle button[hidden] { display: none; }
.tk-product-related-section {
  display: grid;
  gap: 12px;
  margin-top: 8px;
}
.tk-product-related-section header h2 {
  margin: 0;
  color: var(--tk-leaf-deep);
  font-size: clamp(22px, 3vw, 32px);
  letter-spacing: -0.04em;
}
.tk-product-related-track {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(170px, 220px);
  gap: 12px;
  overflow-x: auto;
  padding-bottom: 4px;
}
.tk-product-related-card {
  display: grid;
  gap: 8px;
  min-height: 170px;
  padding: 12px;
  border-radius: 22px;
  background:
    radial-gradient(circle at 78% 18%, rgba(255,255,255,0.64), transparent 28%),
    linear-gradient(145deg, rgba(255,255,255,0.9), rgba(239,235,222,0.76));
  color: var(--tk-ink);
  text-decoration: none;
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 8%, transparent);
}
.tk-product-related-art {
  min-height: 86px;
  border-radius: 18px;
  background:
    radial-gradient(circle at 52% 34%, rgba(236,255,229,0.84), transparent 18%),
    radial-gradient(circle at 50% 58%, rgba(78,139,72,0.58), rgba(22,63,36,0.9) 66%, rgba(10,28,18,0.98) 100%);
}
.tk-product-related-card[data-related-kind="stores"] .tk-product-related-art {
  border-radius: 18px 18px 28px 12px;
  background:
    radial-gradient(circle at 70% 18%, rgba(255,255,255,0.72), transparent 24%),
    linear-gradient(135deg, color-mix(in srgb, var(--tk-leaf-deep) 96%, transparent), color-mix(in srgb, var(--tk-leaf) 82%, transparent));
}
.tk-product-related-card strong {
  color: var(--tk-leaf-deep);
  font-size: 15px;
}
.tk-product-related-card small {
  color: var(--tk-muted);
  line-height: 1.35;
}
.tk-view-as-pill {
  position: fixed;
  left: 50%;
  bottom: 18px;
  z-index: 43;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--tk-leaf-deep) 88%, transparent);
  color: var(--tk-paper);
  box-shadow: 0 16px 34px rgba(20,20,18,0.2);
  transform: translateX(-50%);
  opacity: 0.9;
}
.tk-view-as-pill span {
  font-size: 12px;
  font-weight: 850;
}
.tk-view-as-pill select {
  border: 0;
  border-radius: 999px;
  padding: 5px 8px;
  background: var(--tk-paper);
  color: var(--tk-leaf-deep);
  font: inherit;
  font-size: 12px;
  font-weight: 900;
}
.tk-settings-head {
  display: grid;
  gap: 8px;
}
.tk-settings-head h1 {
  margin: 0;
  color: var(--tk-leaf-deep);
  font-size: clamp(28px, 5vw, 46px);
  letter-spacing: -0.05em;
}
.tk-settings-head p {
  margin: 0;
  max-width: 680px;
  color: var(--tk-ink-soft);
}
.tk-settings-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
}
.tk-account-accordion-stack {
  display: grid;
  gap: 10px;
}
.tk-account-panel {
  border: var(--tk-account-panel-border, 0);
  border-radius: 18px;
  background: var(--tk-account-panel-background, rgba(255,255,255,0.76));
  box-shadow: var(--tk-account-panel-shadow, 0 16px 36px color-mix(in srgb, var(--tk-leaf-deep) 8%, transparent));
  overflow: clip;
}
.tk-account-panel[open] {
  background: var(--tk-account-panel-background-open, radial-gradient(circle at 96% 12%, color-mix(in srgb, var(--tk-leaf) 12%, transparent), transparent 28%), rgba(255,255,255,0.82));
}
.tk-account-summary {
  display: grid;
  grid-template-columns: minmax(0, 0.72fr) minmax(0, 1fr) auto;
  align-items: center;
  gap: 14px;
  padding: 14px 16px;
  cursor: pointer;
  list-style: none;
}
.tk-account-summary::-webkit-details-marker { display: none; }
.tk-account-summary::after {
  content: "";
  justify-self: end;
  width: 9px;
  height: 9px;
  border-right: 2px solid var(--tk-leaf-deep);
  border-bottom: 2px solid var(--tk-leaf-deep);
  transform: rotate(45deg);
  transition: transform .18s ease;
}
.tk-account-panel[open] .tk-account-summary::after {
  transform: rotate(225deg);
}
.tk-account-summary span {
  color: var(--tk-leaf-deep);
  font-size: clamp(18px, 2vw, 22px);
  font-weight: 900;
  letter-spacing: -0.035em;
}
.tk-account-summary small {
  color: var(--tk-muted);
  font-size: 13px;
  line-height: 1.35;
}
.tk-account-panel-body {
  border-top: 0;
  padding: 12px 14px 14px;
}
.tk-settings-form-inline {
  max-width: none;
  gap: 8px;
}
.tk-account-info-list {
  display: grid;
  gap: 8px;
  margin: 0;
}
.tk-account-info-list div {
  display: grid;
  grid-template-columns: minmax(110px, 0.35fr) minmax(0, 1fr);
  gap: 12px;
  align-items: center;
  padding: 10px 12px;
  border-radius: 14px;
  background: color-mix(in srgb, var(--tk-leaf-deep) 4%, transparent);
}
.tk-account-info-list dt {
  color: var(--tk-muted);
  font-size: 12px;
  font-weight: 800;
  letter-spacing: .08em;
  margin: 0;
  text-transform: uppercase;
}
.tk-account-info-list dd {
  color: var(--tk-ink);
  font-weight: 850;
  margin: 0;
}
.tk-account-privacy-note {
  margin: 0;
  color: var(--tk-ink-soft);
  line-height: 1.5;
}
.tk-account-security-stack {
  display: grid;
  gap: 10px;
}
.tk-account-security-stack p,
.tk-account-security-stack small {
  margin: 0;
  color: var(--tk-ink-soft);
  line-height: 1.45;
}
.tk-account-security-action {
  justify-self: start;
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 16%, transparent);
  border-radius: 999px;
  padding: 10px 14px;
  background: var(--tk-leaf-deep);
  color: #fffaf1;
  font: inherit;
  font-size: 13px;
  font-weight: 900;
  cursor: pointer;
}
.tk-account-security-action + .tk-account-security-action {
  background: color-mix(in srgb, var(--tk-leaf) 13%, transparent);
  color: var(--tk-leaf-deep);
}
.tk-founder-admin-grid,
.tk-account-referral-lists {
  display: grid;
  gap: 10px;
}
.tk-founder-admin-block,
.tk-account-referral-list {
  display: grid;
  gap: 8px;
  padding: 12px;
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 10%, transparent);
  border-radius: 14px;
  background: rgba(255,255,255,0.58);
}
.tk-founder-admin-block h3,
.tk-account-referral-list h4 {
  margin: 0;
  color: var(--tk-leaf-deep);
  font-size: 14px;
  font-weight: 900;
}
.tk-founder-admin-block p,
.tk-account-referral-list p {
  margin: 0;
  color: var(--tk-ink-soft);
  font-size: 12px;
  line-height: 1.45;
}
.tk-founder-admin-block select,
.tk-founder-admin-block input {
  width: min(100%, 520px);
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 14%, transparent);
  border-radius: 12px;
  padding: 10px 12px;
  background: rgba(255,255,255,0.82);
  color: var(--tk-ink);
  font: inherit;
}
.tk-settings-card {
  display: grid;
  gap: 10px;
  min-height: 180px;
  align-content: space-between;
  padding: 20px;
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 12%, transparent);
  border-radius: 24px;
  background:
    radial-gradient(circle at 90% 12%, color-mix(in srgb, var(--tk-leaf) 14%, transparent), transparent 32%),
    rgba(255,255,255,0.78);
  color: var(--tk-ink);
  text-decoration: none;
  box-shadow: 0 16px 38px color-mix(in srgb, var(--tk-leaf-deep) 8%, transparent);
}
.tk-settings-card span {
  color: var(--tk-leaf-deep);
  font-size: 22px;
  font-weight: 900;
  letter-spacing: -0.035em;
}
.tk-settings-card small {
  color: var(--tk-muted);
  font-size: 14px;
  line-height: 1.45;
}
.tk-settings-card strong {
  color: var(--tk-leaf-deep);
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: .12em;
}
.tk-settings-form {
  display: grid;
  gap: var(--tk-settings-card-gap);
  width: 100%;
  max-width: var(--tk-settings-max-width);
  margin-inline: auto;
}
.tk-settings-shell {
  width: min(100%, var(--tk-settings-max-width));
  margin-inline: auto;
  background: transparent;
  border: 0;
  box-shadow: none;
}
.tk-settings-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 16px;
  padding: var(--tk-settings-card-padding);
  border: 1px solid var(--tk-settings-card-border);
  border-radius: var(--tk-settings-card-radius);
  background: var(--tk-settings-card-bg);
  box-shadow: var(--tk-settings-card-shadow);
}
.tk-settings-row span {
  color: var(--tk-ink);
  font-weight: 850;
}
.tk-settings-label {
  display: grid;
  gap: 3px;
}
.tk-settings-label strong {
  color: var(--tk-ink);
}
.tk-settings-label small {
  color: var(--tk-ink-soft);
  font-weight: 650;
  line-height: 1.35;
}
.tk-settings-row select {
  justify-self: end;
  width: var(--tk-settings-control-width);
  max-width: 100%;
  min-height: 40px;
  border-radius: 14px;
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 18%, transparent);
  background: var(--tk-paper);
  color: var(--tk-leaf-deep);
  font: inherit;
  font-weight: 800;
  padding: 0 12px;
}
.tk-settings-row-toggle input {
  justify-self: end;
  width: 48px;
  height: 26px;
  accent-color: var(--tk-leaf-deep);
}
:root[data-theme="dark"] .tk-settings-row {
  background: var(--tk-settings-card-bg-dark);
  border-color: var(--tk-settings-card-border-dark);
  box-shadow: var(--tk-settings-card-shadow-dark);
}
:root[data-theme="dark"] .tk-settings-row select,
:root[data-theme="dark"] .tk-founder-admin-block input,
:root[data-theme="dark"] .tk-spin-admin input {
  /* Founder live edit 2026-04-29: account/settings/admin controls in dark
     mode must not keep low-contrast dark-green borders on dark cards. Text
     uses the remapped regular green token; borders use theme.darkMode.line. */
  background: var(--tk-paper-strong);
  border-color: var(--tk-line);
  color: var(--tk-leaf-deep);
}
:root[data-theme="dark"] .tk-spin-admin pre {
  background: var(--tk-paper-strong);
  border: 1px solid var(--tk-line);
  color: var(--tk-ink-soft);
}
.tk-product-copy,
.tk-store-copy {
  display: grid;
  gap: 12px;
}
.tk-product-copy h1,
.tk-store-copy h1 {
  margin: 0;
  color: var(--tk-leaf-deep);
  font-size: clamp(30px, 4vw, 54px);
  line-height: 0.96;
  letter-spacing: -0.055em;
}
.tk-product-copy p,
.tk-store-copy p { margin: 0; color: var(--tk-ink-soft); }
.tk-detail-metrics {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.tk-detail-metrics span {
  border-radius: 999px;
  padding: 7px 11px;
  background: color-mix(in srgb, var(--tk-leaf-deep) 8%, transparent);
  color: var(--tk-leaf-deep);
  font-weight: 700;
  font-size: 12px;
}
.tk-image-source-grid,
.tk-store-menu-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
}
.tk-image-source,
.tk-store-menu-card {
  border-radius: 18px;
  padding: 14px;
  background: var(--tk-paper);
  border: 1px solid var(--tk-line);
}
.tk-image-source[data-source="client"] {
  background: linear-gradient(135deg, var(--tk-leaf-deep), #2f7f4d);
  color: white;
}
.tk-image-source h3,
.tk-store-menu-card h3 { margin: 0 0 8px; font-size: 15px; }
.tk-store-menu-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}
.tk-store-menu-card-head h3 {
  margin: 0;
}
.tk-live-inventory-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-height: 28px;
  padding: 6px 10px;
  border-radius: 999px;
  background: var(--tk-live-inventory-badge-bg, color-mix(in srgb, var(--tk-leaf) 14%, transparent));
  color: var(--tk-live-inventory-badge-color, var(--tk-leaf));
  font-size: 11px;
  font-weight: 1000;
  letter-spacing: .1em;
  white-space: nowrap;
}
.tk-live-inventory-badge::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: currentColor;
  box-shadow: 0 0 0 4px color-mix(in srgb, currentColor 18%, transparent);
}
body[data-tk-animations="on"] .tk-live-inventory-badge[data-pulse="true"]::before {
  animation: tkStatusPulse 1.8s ease-in-out infinite;
}
.tk-image-source ul,
.tk-store-menu-card ul { margin: 0; padding-left: 18px; color: inherit; opacity: 0.82; }
.tk-store-hero {
  display: grid;
  grid-template-columns: 120px minmax(0, 1fr);
  gap: 18px;
  align-items: center;
}
.tk-store-logo {
  position: relative;
  width: 110px;
  aspect-ratio: 1;
  border-radius: 28px;
  display: grid;
  place-items: center;
  color: white;
  background:
    radial-gradient(circle at 35% 24%, rgba(255,255,255,0.42), transparent 28%),
    linear-gradient(135deg, var(--tk-leaf), var(--tk-leaf-deep));
  box-shadow: 0 18px 38px color-mix(in srgb, var(--tk-leaf-deep) 20%, transparent);
}
.tk-store-logo svg { width: 58px; height: 58px; }
.tk-store-verified-badge {
  /* Founder missed-items pass 2026-04-30 (item 4): the verified treatment on
     company/store pages is the small regular-green check badge — no plain
     "Verified" text label. The badge keeps an aria-label for accessibility
     while the visual is icon-only. Used here on the store hero logo. */
  position: absolute;
  right: -6px;
  top: -6px;
  width: 22px;
  height: 22px;
  border-radius: 999px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  background: var(--tk-verified-green);
  color: var(--tk-paper);
  box-shadow: 0 10px 24px color-mix(in srgb, var(--tk-leaf-deep) 18%, transparent);
}
.tk-store-verified-badge svg {
  width: 14px;
  height: 14px;
  display: block;
}
.tk-inline-verified-check {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  height: 14px;
  margin-left: 4px;
  border-radius: 999px;
  background: var(--tk-verified-green);
  color: var(--tk-paper);
  vertical-align: -2px;
}
.tk-inline-verified-check svg {
  width: 10px;
  height: 10px;
}
.tk-store-note {
  border-left: 4px solid var(--tk-leaf);
  padding: 10px 12px;
  background: color-mix(in srgb, var(--tk-leaf) 8%, transparent);
  border-radius: 0 14px 14px 0;
  color: var(--tk-ink-soft);
}
.tk-store-analytics-card {
  display: grid;
  gap: 12px;
  padding: 14px;
  border-radius: 18px;
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 11%, transparent);
  background:
    radial-gradient(circle at 94% 10%, color-mix(in srgb, var(--tk-leaf) 13%, transparent), transparent 30%),
    rgba(255,255,255,0.8);
}
.tk-store-analytics-card h3 {
  margin: 0;
  color: var(--tk-leaf-deep);
  font-size: 15px;
}
.tk-store-analytics-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 10px;
}
.tk-store-analytics-grid article {
  display: grid;
  gap: 4px;
  padding: 12px;
  border-radius: 16px;
  background: color-mix(in srgb, var(--tk-leaf-deep) 6%, transparent);
}
.tk-store-analytics-grid span {
  color: var(--tk-muted);
  font-size: 11px;
  font-weight: 900;
  letter-spacing: .12em;
  text-transform: uppercase;
}
.tk-store-analytics-grid strong {
  color: var(--tk-leaf-deep);
  font-size: 22px;
}
.tk-store-product-grid,
.tk-store-service-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 10px;
}
.tk-store-product-grid article,
.tk-store-service-grid article {
  display: grid;
  gap: 4px;
  padding: 12px;
  border-radius: 16px;
  background: color-mix(in srgb, var(--tk-leaf-deep) 6%, transparent);
}
.tk-store-product-grid strong,
.tk-store-service-grid strong {
  color: var(--tk-leaf-deep);
}
.tk-store-product-grid span,
.tk-store-service-grid span,
.tk-store-digital-items p {
  color: var(--tk-muted);
  font-size: 12px;
}
.tk-store-service-card {
  border-radius: 18px;
  padding: 14px;
  background:
    radial-gradient(circle at 90% 15%, color-mix(in srgb, var(--tk-leaf) 13%, transparent), transparent 32%),
    rgba(255,255,255,0.78);
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 11%, transparent);
}
.tk-store-service-card h3,
.tk-store-digital-items h3,
.tk-store-digital-items p {
  margin: 0 0 8px;
}
.tk-store-digital-items {
  background:
    radial-gradient(circle at 92% 12%, rgba(216,143,60,0.14), transparent 30%),
    rgba(255,255,255,0.82);
}
.tk-digital-products-compact {
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
}
/* Founder missed-items pass 2026-04-30 (item 6): store/business page section
   structure is exactly PRODUCTS -> REVIEWS -> ABOUT with larger section
   titles. Cards inside each section keep their own surface; the page
   itself sits transparent on the site background (item 5). */
.tk-store-section {
  display: grid;
  gap: 14px;
  padding: 0;
  background: transparent;
  border: 0;
  border-radius: 0;
  order: var(--tk-store-section-order, auto);
}
.tk-store-section[data-store-section-order="1"] { order: 1; }
.tk-store-section[data-store-section-order="2"] { order: 2; }
.tk-store-section[data-store-section-order="3"] { order: 3; }
.tk-store-section-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 4px 0 6px;
}
.tk-store-section-head h2 {
  margin: 0;
  font-size: clamp(20px, 2.6vw, 26px);
  font-weight: 900;
  letter-spacing: 0.01em;
  color: var(--tk-ink);
}
.tk-store-product-card {
  display: grid;
  gap: 8px;
  padding: 12px;
  border-radius: 18px;
  background: var(--tk-paper);
  border: 1px solid var(--tk-line);
  box-shadow: 0 8px 18px color-mix(in srgb, var(--tk-leaf-deep) 6%, transparent);
}
.tk-store-product-art {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  border-radius: 14px;
  background:
    radial-gradient(circle at 32% 28%, rgba(255,255,255,0.55), transparent 38%),
    linear-gradient(135deg, var(--tk-leaf), var(--tk-leaf-deep));
}
.tk-store-product-card strong { color: var(--tk-ink); font-size: 14px; }
.tk-store-product-card span { color: var(--tk-muted); font-size: 12px; }
.tk-store-product-sizes {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.tk-store-product-sizes button {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  min-width: 56px;
  padding: 6px 8px;
  border: 1px solid var(--tk-line);
  border-radius: 12px;
  background: rgba(255,255,255,0.85);
  color: var(--tk-ink);
  font: inherit;
  cursor: pointer;
}
.tk-store-product-sizes button[data-active="true"] {
  border-color: var(--tk-leaf);
  background: color-mix(in srgb, var(--tk-leaf) 12%, transparent);
  color: var(--tk-leaf-deep);
}
.tk-store-product-sizes b { font-size: 12px; font-weight: 900; }
.tk-store-product-sizes small { font-size: 11px; opacity: 0.78; }
.tk-store-product-price {
  font-weight: 900;
  color: var(--tk-leaf-deep);
}
.tk-store-reviews-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 10px;
}
.tk-store-review-card {
  display: grid;
  gap: 6px;
  padding: 12px 14px;
  border-radius: 16px;
  background: var(--tk-paper);
  border: 1px solid var(--tk-line);
  box-shadow: 0 6px 14px color-mix(in srgb, var(--tk-leaf-deep) 5%, transparent);
}
.tk-store-review-card header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}
.tk-store-review-card header strong { color: var(--tk-ink); }
.tk-store-review-card header span { color: var(--tk-leaf-deep); font-weight: 900; font-size: 12px; }
.tk-store-review-card p { margin: 0; color: var(--tk-ink-soft); font-size: 13px; }
.tk-store-review-card small { color: var(--tk-muted); font-size: 11px; }
.tk-store-reviews-empty {
  margin: 0;
  padding: 12px 14px;
  border-radius: 14px;
  background: color-mix(in srgb, var(--tk-leaf-deep) 5%, transparent);
  color: var(--tk-muted);
  font-size: 13px;
}
.tk-store-about-body {
  margin: 0 0 6px;
  color: var(--tk-ink-soft);
  font-size: 14px;
  line-height: 1.55;
}
.tk-store-digital-block {
  display: grid;
  gap: 8px;
  padding: 12px 14px;
  border-radius: 18px;
  background:
    radial-gradient(circle at 92% 12%, rgba(216,143,60,0.14), transparent 30%),
    rgba(255,255,255,0.82);
  border: 1px solid var(--tk-line);
}
.tk-store-digital-block h3 {
  margin: 0;
  font-size: 14px;
  color: var(--tk-leaf-deep);
}
.tk-store-digital-block p {
  margin: 0;
  color: var(--tk-muted);
  font-size: 12px;
}
.tk-store-founder-tools {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  border: 1px dashed color-mix(in srgb, var(--tk-leaf-deep) 22%, transparent);
  border-radius: 18px;
  padding: 12px;
  background: rgba(216,234,216,0.22);
}
.tk-store-founder-tools button {
  border: 0;
  border-radius: 999px;
  padding: 10px 14px;
  background: var(--tk-leaf-deep);
  color: var(--tk-paper);
  font-weight: 900;
  cursor: pointer;
}
.tk-store-founder-tools button:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}
.tk-store-founder-tools p {
  flex: 1 1 220px;
  margin: 0;
  color: var(--tk-muted);
  font-size: 12px;
}

.tk-digital-shell {
  gap: 22px;
}
.tk-digital-category-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
  gap: 10px;
}
.tk-digital-category {
  display: inline-flex;
  min-height: 48px;
  align-items: center;
  justify-content: center;
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 14%, transparent);
  border-radius: 16px;
  background: linear-gradient(145deg, rgba(255,255,255,0.9), rgba(216,234,216,0.45));
  color: var(--tk-leaf-deep);
  font-weight: 900;
  text-decoration: none;
}
.tk-digital-products {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 14px;
}
.tk-digital-card {
  display: grid;
  grid-template-columns: 68px 1fr;
  gap: 12px;
  align-items: center;
  border: 1px solid color-mix(in srgb, var(--tk-leaf-deep) 12%, transparent);
  border-radius: 20px;
  padding: 14px;
  background: rgba(255,255,255,0.82);
  box-shadow: var(--tk-card-shadow, 0 16px 34px color-mix(in srgb, var(--tk-leaf-deep) 8%, transparent));
}
.tk-digital-card-art {
  width: 68px;
  height: 68px;
  border-radius: 18px;
  background:
    radial-gradient(circle at 38% 28%, rgba(255,255,255,0.9), transparent 24%),
    linear-gradient(145deg, var(--tk-leaf-deep), var(--tk-leaf));
}
.tk-digital-card p,
.tk-digital-card span {
  margin: 0;
  color: var(--tk-muted);
  font-size: 12px;
  font-weight: 800;
}
.tk-digital-card h2 {
  margin: 2px 0 5px;
  color: var(--tk-ink);
  font-size: 17px;
}

body.tk-product-route [data-tk-order],
body.tk-store-route [data-tk-order],
body.tk-digital-route [data-tk-order] {
  display: none;
}

body.tk-design-playful {
  --tk-card-radius: 26px;
  --tk-card-shadow: 0 18px 38px color-mix(in srgb, var(--tk-leaf-deep) 11%, transparent);
}
body.tk-design-playful .tk-card,
body.tk-design-playful .tk-detail-shell {
  border-radius: calc(var(--tk-card-radius) + 4px);
}

@media (max-width: 980px) {
  .tk-row {
    --tk-row-card-basis-active: var(--tk-row-card-basis-tablet, 220px);
  }
  .tk-in-page-ad-placement,
  .tk-homepage-inserted-content {
    --tk-ad-grid-columns-active: var(--tk-ad-grid-columns-tablet, repeat(auto-fit, minmax(210px, 1fr)));
  }
  body.tk-page {
    padding-top: calc(var(--tk-mobile-header-height, 124px) + env(safe-area-inset-top, 0px));
    scroll-padding-top: calc(var(--tk-mobile-header-height, 124px) + env(safe-area-inset-top, 0px));
  }
  body[data-tk-route-type="homepage"].tk-page {
    padding-top: 0;
    scroll-padding-top: 0;
  }
  body[data-tk-route-type="homepage"][data-tk-homepage-map-mode="activeOrderCompact"].tk-page {
    /* Founder emergency recovery 2026-04-29: when an active order is visible on
       the homepage, it is not the browsing map hero and must not sit under the
       fixed mobile header. The no-order browsing hero keeps zero top padding so
       the map can fade behind the header/menu cluster. */
    padding-top: calc(var(--tk-mobile-header-height, 124px) + env(safe-area-inset-top, 0px));
    scroll-padding-top: calc(var(--tk-mobile-header-height, 124px) + env(safe-area-inset-top, 0px));
  }
  .tk-header {
    position: fixed;
    /* Founder LIVE EDIT 2026-05-01 (PRIVACY UPDATE BAR + AUDIT PASS):
       playwright headless audit confirmed the mobile banner was being
       drawn UNDER the fixed header on /demo (banner z-index auto, header
       z-index 100) and BELOW the header on /demo/account (because the
       body had padding-top:124px to reserve space for the fixed header).
       Founder's spec PART 1 — "true top-of-site bar that pushes the
       entire site container down" — is honored here by pushing the
       fixed header down by --tk-legal-banner-mobile-h whenever the
       banner is present. Demo.js measures the banner and sets the CSS
       var; on dismiss the var animates to 0 so the header slides
       smoothly back to top:0. */
    top: var(--tk-legal-banner-mobile-h, 0px);
    transition: top var(--tk-legal-banner-collapse-ms, 280ms) var(--tk-legal-banner-easing, cubic-bezier(0.4, 0, 0.2, 1));
    left: 0;
    right: 0;
    width: 100%;
    /* Founder LIVE EDIT BLOCK 2026-05-01: mobile menu z-index lifted
       so page content can never scroll over it. Stays below modal
       dialogs (140).
       Founder LIVE EDIT 2026-05-01 (FIRST VISIT STACK ORDER FIX):
       bumped from 100 → 4000 to match the new strict hierarchy
       where the menu/header is at 4000, privacy banner at 5000,
       popups at 8500, age check at 9000, location picker at 9999. */
    z-index: 4000;
    background: var(--tk-mobile-header-panel-bg);
    transform: translateZ(0);
    will-change: transform;
  }
  /* Founder LIVE EDIT 2026-05-01 (PRIVACY UPDATE BAR audit fix): make
     the banner a fixed top-of-viewport element on mobile so it ALWAYS
     paints above the fixed header, never overlays page content (it
     sits at top:0), and pushes the header + body padding down by
     --tk-legal-banner-mobile-h.
     Founder LIVE EDIT 2026-05-01 (FIRST VISIT STACK ORDER FIX):
     bumped from 105 → 5000 (Founder Privacy Banner tier — above
     header at 4000, below popups at 8500). */
  .tk-legal-banner {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 5000;
  }
  /* Body padding-top must include banner height on EVERY mobile route
     so the first content row is never tucked under the fixed header.
     The two body[data-tk-route-type] rules above set the base padding;
     this rule adds the banner offset on top. */
  body.tk-page {
    padding-top: calc(var(--tk-legal-banner-mobile-h, 0px) + var(--tk-mobile-header-height, 124px) + env(safe-area-inset-top, 0px));
    scroll-padding-top: calc(var(--tk-legal-banner-mobile-h, 0px) + var(--tk-mobile-header-height, 124px) + env(safe-area-inset-top, 0px));
  }
  body[data-tk-route-type="homepage"].tk-page {
    /* Homepage map fades behind the fixed header — keep zero base
       padding so the hero map reaches the top edge — but still
       reserve room for the banner if present so the map doesn't
       hide under the announcement bar. */
    padding-top: var(--tk-legal-banner-mobile-h, 0px);
    scroll-padding-top: var(--tk-legal-banner-mobile-h, 0px);
  }
  /* Founder LIVE EDIT 2026-04-30 (one menu, every route): mobile header
     panel + fade unscoped from body[data-tk-route-type="homepage"] so
     the same .tk-header chrome renders identically on Account, Order,
     Store, Product, Favorites, Settings, Digital. */
  .tk-header {
    border-bottom: 0;
    /* Founder latest correction 2026-04-29: restore the solid mobile header
       panel behind logo/search. Only the panel bottom fades to transparent;
       the top area must not become transparent or green-hazed. */
    background: var(--tk-mobile-header-panel-bg);
    box-shadow: none;
  }
  /* Founder LIVE EDIT BLOCK 2026-04-30 (mobile header fade — copy map fade
     method): the previous mobile header fade stacked TWO sources — a
     linear-gradient on the .tk-header background itself (which produced
     a visible band crossing the green category area) AND a separate
     ::after extension below. The result was duplicate fade lines and a
     white-tint glow above the category bar. The map's bottom fade
     pattern (.tk-order-map::after) is the working reference: ONE
     pseudo-element, position absolute at the bottom, height clamped, a
     linear-gradient from the panel color to transparent, pointer-events
     none, no border or shadow. We adopt that exact pattern here. */
  body[data-tk-mobile-header-fade="on"] .tk-header {
    /* Founder undo 2026-05-01: mask-image on the header itself was
       making the menu/search/green-bar transparent. NOT what Founder
       wanted. Reverted. Header is plain solid cream. No fade
       applied here. Awaiting explicit Founder confirmation before
       applying any fade design. */
    background: var(--tk-mobile-header-panel-bg);
    -webkit-mask-image: none;
    mask-image: none;
  }
  body[data-tk-mobile-header-fade="on"] .tk-header::after,
  .tk-header::after,
  body[data-tk-homepage-map-mode="homepageHero"] .tk-header::after {
    /* Founder restore 2026-05-01: bring back the working ::after fade
       extension that existed BEFORE the mask-image-on-header attempt.
       Header itself stays fully solid (menu/search/green bar opaque).
       Below the header bottom edge, this strip fades from cream
       panel-bg to transparent, dissolving the hard horizontal cutoff
       line where header meets page content. pointer-events:none so
       it doesn't block taps. */
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    height: var(--tk-mobile-header-bottom-fade-height, 30px);
    z-index: 0;
    pointer-events: none;
    background: linear-gradient(180deg, var(--tk-mobile-header-panel-bg) 0%, transparent 100%);
    box-shadow: none;
    border: 0;
  }
  .tk-header-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    grid-template-columns: none;
    position: relative;
    min-height: 104px;
    padding: 14px 14px 0;
    row-gap: 0;
    column-gap: 10px;
    transform: translateY(var(--tk-mobile-menu-vertical-offset, 0px));
  }
  .tk-mobile-menu {
    position: absolute;
    left: clamp(12px, 3.5vw, 18px);
    top: 14px;
    display: inline-grid;
    place-items: center;
    width: 34px;
    height: 34px;
    border: 0;
    background: transparent;
    color: var(--tk-leaf-deep);
    cursor: pointer;
    order: 0;
  }
  .tk-mobile-menu span {
    width: 20px;
    height: 2px;
    background: currentColor;
    border-radius: 99px;
  }
  .tk-mobile-menu em { display: none; }
  .tk-mobile-favorites-action {
    position: absolute;
    left: calc(clamp(12px, 3.5vw, 18px) + 34px);
    top: 14px;
    display: inline-grid !important;
    place-items: center;
    width: 34px;
    height: 34px;
    color: var(--tk-leaf-deep);
    text-decoration: none;
  }
  .tk-logo-shell {
    /* Founder live edit 2026-04-30 (item 2) + LIVE EDIT BLOCK 2026-04-30
       (item 2 — logo admin geometry): mobile logo top alignment is
       restored. The horizontal offset adds to the centering translate so
       the admin slider can fine-tune the X position; the vertical offset
       adds to the top:14px row anchor; size is fully driven by the
       mobile-specific CSS var which logo-settings.json#geometry.mobile.size
       writes via demo.js loadSiteLogoSettings. */
    position: absolute;
    left: 50%;
    top: calc(14px + var(--tk-mobile-brand-logo-offset-y, 0px));
    transform: translate(calc(-50% + var(--tk-mobile-brand-logo-offset-x, 0px)), 0);
    order: 0;
    justify-content: center;
    align-items: var(--tk-mobile-brand-logo-vertical-align, center);
    z-index: 1;
  }
  .tk-logo {
    justify-content: center;
    align-items: var(--tk-mobile-brand-logo-vertical-align, center);
  }
  .tk-logo-mark {
    width: var(--tk-mobile-brand-mark-size, 30px);
    height: var(--tk-mobile-brand-mark-size, 30px);
  }
  .tk-city {
    position: absolute;
    left: calc(clamp(12px, 3.5vw, 18px) + 68px);
    top: 14px;
    order: 0;
    grid-column: auto;
  }
  .tk-city-btn {
    width: 34px;
    height: 34px;
    padding: 0;
    justify-content: center;
    box-shadow: none;
    background: transparent;
    border-color: transparent;
    color: var(--tk-leaf-deep);
  }
  .tk-city-btn > span,
  .tk-city-btn .tk-icon-sm {
    display: none;
  }
  .tk-main-menu {
    display: none;
  }
	  .tk-search {
	    /* Founder settings/mobile correction 2026-04-29: mobile header spacing
	       is token-owned. The icon row control size and search top offset come
	       from header.mobileHeader; category attachment is now zero-gap per
	       config, not the older half-gap rule.
	       Founder LIVE EDIT 2026-05-01: --tk-mobile-search-offset-y adds an
	       admin-driven vertical nudge (parallel to the existing desktop slider). */
	    order: 2;
	    flex: 0 0 100%;
	    width: 100%;
	    min-width: 0;
	    grid-column: 1 / -1;
	    margin-top: var(--mobile-header-search-top-offset, calc(var(--mobile-header-icons-to-search-gap, 8px) + var(--mobile-header-icon-control-size, 34px)));
	    transform: translateY(var(--tk-mobile-search-offset-y, 0px));
	  }
  .tk-categories-shell {
    /* Founder LIVE EDIT BLOCK 2026-04-30 (item 5 — overlap-bottom mobile):
       negative margin-bottom (driven by --tk-mobile-category-overlap-bottom
       from categoryMenuLayout.mobileGreenBarOverlapBottom JSON) pulls the
       green rail's bottom past the cream panel so a few less px of white
       show below the green on mobile.
       Founder LIVE EDIT 2026-05-01 (MOBILE GREEN CATEGORY BAR WIDTH
       EXPANSION): the mobile mask-image fade now uses a smaller
       --tk-mobile-category-menu-edge-fade-width (24px) instead of
       the desktop 56px so the visible/fade balance matches Founder's
       mock — visible items extend closer to the search/mic icon
       bounds with only a thin fade at each edge rather than the
       prior heavy 56px fade that ate ~14% of the bar on each side. */
    order: 3;
    flex: 0 0 var(--tk-mobile-category-bar-width);
    width: var(--tk-mobile-category-bar-width);
    /* Founder PASS 54 2026-05-01: phone default — overridden for tablet
       widths by the nested min-width:721px rule below. */
    max-width: var(--tk-mobile-category-bar-max-width);
    margin: calc(var(--mobile-search-to-categories-gap) + var(--mobile-header-category-attach-offset, 0px)) auto calc(-1 * var(--tk-mobile-category-overlap-bottom, 0px));
    padding: var(--tk-mobile-category-bar-padding-y) var(--tk-mobile-category-bar-padding-x);
    background: var(--tk-category-menu-desktop-bg);
    overflow: hidden;
    isolation: isolate;
    position: relative;
    transform: translateY(var(--tk-mobile-category-offset-y, 0px));
    /* Founder LIVE EDIT 2026-05-01 (mobile category text WIDTH, not
       just glow): mask fade reduced to 10px so the visible text
       region extends nearly to the outer bounds. With the shell
       padding-x dropped to 10px in JSON (mobileCategoryBarPaddingX),
       the actual scrollable .tk-categories child gets the full
       width-minus-20px usable area (matching the search bar width
       almost edge-to-edge). The fade still exists at the true
       outer edges (10px each side) but the menu text starts/ends
       much closer to the search and mic icons above. */
    -webkit-mask-image:
      linear-gradient(90deg, transparent 0, #000 var(--tk-mobile-category-menu-edge-fade-width, 24px), #000 calc(100% - var(--tk-mobile-category-menu-edge-fade-width, 24px)), transparent 100%);
    mask-image:
      linear-gradient(90deg, transparent 0, #000 var(--tk-mobile-category-menu-edge-fade-width, 24px), #000 calc(100% - var(--tk-mobile-category-menu-edge-fade-width, 24px)), transparent 100%);
  }
  /* Founder PASS 54 2026-05-01 (tablet category-bar width override): on
     tablet widths (721-980px) the bar uses --tk-tablet-category-bar-max-width
     instead of the phone token. iPad portrait (~768px) and other tablet
     viewports get their own tuned width without affecting phones (≤720px)
     or desktop (≥981px). */
  @media (min-width: 721px) {
    .tk-categories-shell {
      max-width: var(--tk-tablet-category-bar-max-width);
    }
  }
  .tk-categories-shell::before,
  .tk-categories-shell::after {
    content: none;
    position: absolute;
    top: 0;
    bottom: 0;
    z-index: 2;
    width: var(--tk-category-menu-edge-fade-width);
    pointer-events: none;
  }
  .tk-categories-shell::before {
    left: 0;
    background: linear-gradient(90deg, var(--tk-category-menu-edge-fade-color), transparent);
  }
  .tk-categories-shell::after {
    right: 0;
    background: linear-gradient(270deg, var(--tk-category-menu-edge-fade-color), transparent);
  }
  .tk-header-actions {
    position: absolute;
    right: clamp(12px, 3.5vw, 18px);
    top: 14px;
    order: 0;
    flex: 0 0 auto;
    justify-self: end;
    gap: 2px;
    height: 34px;
  }
  .tk-header-actions .tk-favorites-action,
  .tk-auth-signup,
  .tk-logout-link,
  .tk-auth-link span {
    display: none !important;
  }
  .tk-header-actions .tk-icon-action,
  .tk-header-actions .tk-auth-link,
  .tk-header-actions .tk-pill-cart {
    width: 34px;
    height: 34px;
    min-width: 34px;
    padding: 0;
    display: inline-grid;
    place-items: center;
    border: 0;
    background: transparent;
    box-shadow: none;
    color: var(--tk-leaf-deep);
  }
  .tk-header-actions .tk-auth-link[hidden] {
    display: none !important;
  }
  .tk-header-actions .tk-account-link {
    width: 36px;
    height: 36px;
    min-width: 36px;
    margin-top: -1px;
    color: var(--tk-leaf-deep);
  }
  .tk-logo-picker-toggle {
    position: absolute;
    right: -22px;
    top: 7px;
    width: 20px;
    height: 20px;
  }
  .tk-logo-picker {
    left: 50%;
    transform: translateX(-50%);
    top: calc(100% + 10px);
  }
	  .tk-categories {
	    max-height: 38px;
	    width: 100%;
	    margin: 0;
	    padding: 0;
	    gap: var(--mobile-category-item-gap);
	    overflow-x: auto;
	    overflow-y: hidden;
	    align-items: center;
	    transition: max-height .18s ease;
	  }
	  .tk-categories.tk-categories-open {
	    max-height: 38px;
	    overflow-x: auto;
	  }
	  .tk-cat {
	    position: relative;
	    z-index: 1;
	    border: 0;
	    background: transparent;
	    color: var(--mobile-category-text-color);
	    border-radius: 0;
	    padding: var(--mobile-category-item-padding-y) var(--mobile-category-item-padding-x);
	    font-size: var(--mobile-category-font-size);
	    line-height: 1.08;
	    font-weight: 900;
	  }
	  .tk-cat::before {
	    content: "";
	    position: absolute;
	    inset: var(--tk-category-active-glow-inset);
	    z-index: -1;
	    border-radius: 999px;
	    background: var(--tk-category-active-glow-bg);
	    opacity: 0;
	    pointer-events: none;
	  }
	  .tk-cat:hover,
	  .tk-cat[data-active="true"] {
	    color: var(--mobile-category-active-text-color);
	    background: transparent;
	  }
	  .tk-cat:hover::before,
	  .tk-cat[data-active="true"]::before {
	    opacity: 1;
	  }
	  .tk-row-track {
		    grid-auto-columns: minmax(0, var(--tk-row-card-basis-active, var(--tk-row-card-basis-mobile, calc((100% - 24px) / 3))));
		    gap: var(--tk-row-track-gap-mobile, 12px);
		    background: linear-gradient(90deg, color-mix(in srgb, var(--tk-leaf) 4%, transparent), transparent 16%, transparent 84%, color-mix(in srgb, var(--tk-leaf) 4%, transparent));
	    margin-inline: calc(-1 * clamp(12px, 3vw, 24px));
	    padding-inline: clamp(12px, 3vw, 24px);
	  }
  .tk-priority-signup-panel {
    grid-template-columns: 1fr;
    justify-items: center;
    text-align: center;
    background: rgba(255, 255, 255, 0.96);
    color: var(--tk-leaf-deep);
    border-color: color-mix(in srgb, var(--tk-leaf) 28%, transparent);
    box-shadow: 0 4px 14px color-mix(in srgb, var(--tk-leaf-deep) 8%, transparent);
  }
  .tk-priority-signup-panel .tk-priority-signup-copy strong {
    color: var(--tk-leaf-deep);
  }
  .tk-priority-signup-panel .tk-priority-signup-copy span,
  .tk-priority-signup-panel .tk-priority-signup-copy em {
    color: var(--tk-ink-soft);
  }
  .tk-priority-signup-actions {
    width: 100%;
    justify-content: center;
    flex-wrap: wrap;
  }
  .tk-homepage-map-hero {
    order: -20;
    height: var(--tk-platform-map-homepage-height-mobile);
    min-height: var(--tk-platform-map-homepage-height-mobile);
    /* Founder LIVE EDIT 2026-05-01 (homepage map mobile start position):
       On mobile the header is position:fixed so the page has padding-top:0
       for the homepage, meaning the map hero started at y=0 and the fixed
       header covered its top --tk-mobile-header-height pixels. Founder:
       "make sure the home page map starts from where the search bar ends."
       This margin-top pushes the map hero down to start exactly where the
       bottom of the fixed header (search bar + category bar) ends. */
    margin-top: calc(var(--tk-mobile-search-bar-height, 70px) - var(--tk-mobile-map-top-offset, 50px) + env(safe-area-inset-top, 0px));
  }
	  body[data-tk-route-type="homepage"][data-tk-homepage-map-mode="activeOrderCompact"] .tk-active-order-map {
	    min-height: var(--tk-platform-map-active-order-height-mobile);
	  }
	  body[data-tk-route-type="homepage"][data-tk-homepage-map-mode="activeOrderCompact"] .tk-order {
	    margin-top: var(--tk-mobile-active-order-top-offset, -8px);
	  }
  .tk-delivered-confirmation {
    width: calc(100% - 24px);
    grid-template-columns: 1fr;
    padding: 16px;
    border-radius: 18px;
  }
  .tk-delivered-reward-arrow {
    margin-bottom: var(--tk-delivered-arrow-clearance-mobile, 86px);
  }
  .tk-delivered-cta-arrow {
    right: var(--tk-delivered-arrow-mobile-right, 0px);
    top: var(--tk-delivered-arrow-mobile-top, calc(100% - 1px));
    width: var(--tk-delivered-arrow-mobile-width, 156px);
    height: var(--tk-delivered-arrow-mobile-height, 176px);
  }
  .tk-delivered-confirm-video {
    display: inline-flex;
    place-items: center;
  }
  .tk-delivered-phone-required {
    display: none;
  }
  .tk-map-article-carousel {
    /* Founder zero-blocker live edit 2026-04-30 (P2): mobile news/guide
       carousel proportions must mirror the desktop "map overlay" relationship
       at mobile scale. Width/scale/overlap all come from
       homepage_rows.mapHeroArticleCarousel.mobile* via demo.js so future
       tweaks stay JSON-owned. */
    width: var(--tk-map-hero-article-mobile-width, min(94vw, 560px));
    max-width: var(--tk-map-hero-article-mobile-width, min(94vw, 560px));
    margin-top: calc(-1 * var(--tk-map-hero-article-overlap-mobile));
    transform: scale(var(--tk-map-hero-article-mobile-scale));
    transform-origin: top center;
  }
  .tk-public-order-preview {
    /* Founder LIVE EDIT BLOCK 2026-04-30 (item 5 — Preview Order on mobile
       belongs to the map, not the carousel): on mobile, the Preview Order
       button is centered on the map itself, anchored at the vertical
       middle of the map's visible area instead of riding the news
       carousel's overlap. The button no longer shifts as the carousel
       outset changes. The horizontal centering via translateX(-50%) is
       inherited from the base rule. The mobile-only override uses top
       50% with a translateY(-50%) so the button sits dead-center of the
       map regardless of carousel height. */
    top: var(--tk-public-order-preview-mobile-top, 50%);
    bottom: auto;
    transform: translate(-50%, -50%);
  }
  .tk-map-article-track {
    -webkit-mask-image: linear-gradient(
      to right,
      transparent 0,
      #000 var(--tk-map-hero-article-mobile-edge-fade-width, 30px),
      #000 calc(100% - var(--tk-map-hero-article-mobile-edge-fade-width, 30px)),
      transparent 100%
    );
            mask-image: linear-gradient(
      to right,
      transparent 0,
      #000 var(--tk-map-hero-article-mobile-edge-fade-width, 30px),
      #000 calc(100% - var(--tk-map-hero-article-mobile-edge-fade-width, 30px)),
      transparent 100%
    );
  }
  .tk-homepage-inserted-content[data-layout="wide"] .tk-in-page-ad-card {
    grid-template-columns: 1fr;
  }
  .tk-section-marker-inner {
    padding-inline: 22px;
  }
	  .tk-card {
	    border-radius: 8px;
	  }
	  .tk-card-art {
	    background:
	      radial-gradient(circle at 52% 38%, rgba(255,255,255,0.62), transparent 28%),
	      radial-gradient(circle at 72% 24%, var(--tk-card-art-glow), transparent 28%),
	      linear-gradient(135deg, rgba(216, 234, 216, 0.9) 0%, color-mix(in srgb, var(--tk-paper) 94%, transparent) 100%);
	    aspect-ratio: 1 / 1;
	  }
	  .tk-card-art svg,
	  .tk-card-art img,
	  .tk-card-art canvas,
	  .tk-card-art .tk-product-media-asset {
	    width: 100%;
	    height: 100%;
	    object-fit: cover;
	  }
  .tk-card-body { padding: 10px; }
  .tk-card-name { font-size: 13px; }
  .tk-card-meta { font-size: 11px; }
  .tk-favorites-track {
    grid-auto-columns: minmax(158px, 178px);
  }
  .tk-location-current,
  /* Founder zero-blocker live edit 2026-04-30: Allow Location button must
     read as a primary CTA with an upward/location arrow before the label.
     Icon comes from demo.js render of location_picker.browserLocationIcon. */
  /* Founder LIVE EDIT 2026-05-01 (location icon baseline alignment):
     "move the location icon slightly down, so it's level with the
     word 'Allow' in 'Allow Location' on desktop AND mobile."
     vertical-align changed from -2px (icon sits 2px below baseline,
     making it look raised vs. the lowercase letters) to -4px so
     the pin/arrow visually aligns with the lowercase x-height of
     "Allow". margin-right preserved. Same value applies to all
     four icon variants (location-pin / arrow / nav / crosshair). */
  .tk-location-allow-arrow,
  .tk-location-allow-pin,
  .tk-location-allow-nav,
  .tk-location-allow-crosshair {
    vertical-align: -4px;
    margin-right: 6px;
  }
  [data-tk-location-browser][data-tk-location-allow="primary"] {
    background: var(--tk-leaf);
    color: #fff;
  }
  /* Founder LIVE EDIT 2026-05-01 (mobile city picker — Allow Location
     must be visible too): the prior @media (max-width: 980px) rule
     hid [data-tk-location-browser] entirely on mobile. Founder's
     real-device report: "On mobile, in the city picker, I don't see
     the Allow location button. It's just on desktop. Make it
     available on mobile too." Removed the display:none override so
     the Allow Location button renders alongside Save on every
     viewport. */
  .tk-product-hero,
  .tk-product-sketch-grid,
  .tk-store-hero,
  .tk-image-source-grid,
  .tk-store-menu-grid {
    grid-template-columns: 1fr;
  }
  .tk-product-pill-group[data-attribute-section="timeOfDay"] .tk-product-attribute-grid {
    /* Founder HARD CORRECTION 2026-05-03 — founder rule: "mobile:
       make time of day columns be 2 like uses and effects".
       Aligns with the parent grid-mobile-columns value of 2. */
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .tk-product-pill-group[data-attribute-section="timeOfDay"] .tk-product-attribute {
    grid-template-columns: 24px minmax(0, 1fr);
    min-height: 46px;
    padding: 8px;
  }
  .tk-product-pill-group[data-attribute-section="timeOfDay"] .tk-product-attribute strong {
    white-space: normal;
    font-size: 11px;
    line-height: 1.12;
  }
  .tk-product-pill-group[data-attribute-section="timeOfDay"] .tk-product-attribute em {
    grid-column: 2;
    justify-self: start;
  }
  .tk-order-dashboard-head,
  .tk-client-dashboard-head,
  .tk-order-dashboard-detail header {
    display: grid;
  }
  .tk-order-dashboard-shell,
  .tk-order-dashboard-columns {
    grid-template-columns: 1fr;
  }
  .tk-order-dashboard-list {
    max-height: 230px;
  }
  .tk-client-dashboard-controls {
    justify-items: stretch;
  }
  /* Founder LIVE EDIT BLOCK 2026-05-01 (mobile 2-column ads — outer grid
     override fix): the previous rule force-collapsed .tk-in-page-ad-grid
     to a single column on every viewport <= 980px, which clobbered the
     --tk-ad-grid-columns-mobile var set by demo.js per-row. Now scoped
     to placements that are NOT explicitly configured as 2 or 3 columns
     so 2/3-col rows render side-by-side using the JS-set var. */
  .tk-in-page-ad-placement:not([data-tk-homepage-columns="2"]):not([data-tk-homepage-columns="3"]) .tk-in-page-ad-grid,
  .tk-homepage-inserted-content:not([data-tk-homepage-columns="2"]):not([data-tk-homepage-columns="3"]) .tk-in-page-ad-grid {
    grid-template-columns: 1fr;
  }
  /* 1-column card internal layout (image + copy + CTA in 3 columns) is
     overridden in 1-col mobile rows where the card needs to stack
     vertically because there's no horizontal room. The 2/3-col card
     internal layout is handled by the [data-tk-homepage-columns]
     selector below. */
  .tk-in-page-ad-placement:not([data-tk-homepage-columns="2"]):not([data-tk-homepage-columns="3"]) .tk-in-page-ad-card,
  .tk-homepage-inserted-content:not([data-tk-homepage-columns="2"]):not([data-tk-homepage-columns="3"]) .tk-in-page-ad-card {
    grid-template-columns: 1fr;
  }
  .tk-in-page-ad-card {
    min-height: 0;
    background: rgba(255, 255, 255, 0.96);
    color: var(--tk-leaf-deep);
    box-shadow: 0 4px 14px color-mix(in srgb, var(--tk-leaf-deep) 8%, transparent);
  }
  .tk-in-page-ad-card .tk-in-page-ad-copy small {
    color: var(--tk-warm);
  }
  .tk-in-page-ad-card .tk-in-page-ad-copy strong {
    color: var(--tk-leaf-deep);
  }
  .tk-in-page-ad-card .tk-in-page-ad-copy em {
    color: var(--tk-ink-soft);
  }
  .tk-in-page-ad-card .tk-in-page-ad-cta {
    background: var(--tk-leaf);
    color: #fff;
  }
  .tk-in-page-ad-media {
    height: 80px;
    aspect-ratio: auto;
    background:
      radial-gradient(circle at 36% 36%, rgba(245, 255, 218, 0.95), transparent 28%),
      radial-gradient(circle at 70% 64%, rgba(121, 214, 113, 0.55), transparent 32%),
      linear-gradient(145deg, rgba(245, 245, 240, 0.96), rgba(214, 234, 214, 0.96));
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--tk-leaf-deep) 10%, transparent);
  }
  .tk-settings-grid,
  .tk-settings-row {
    grid-template-columns: 1fr;
  }
  .tk-account-summary,
  .tk-account-info-list div {
    grid-template-columns: 1fr;
  }
  .tk-account-summary {
    gap: 6px;
    padding-right: 40px;
    position: relative;
  }
  .tk-account-summary::after {
    position: absolute;
    right: 16px;
    top: 20px;
  }
  .tk-product-media { min-height: 310px; }
  .tk-product-left-rail .tk-product-media { min-height: 360px; }
  .tk-product-right-rail h1 { font-size: clamp(38px, 12vw, 58px); }
  .tk-product-category-pills {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
  .tk-product-category-pills .tk-product-pill {
    justify-content: center;
  }
  .tk-product-compact-buy-row {
    justify-content: center;
    flex-wrap: nowrap;
    gap: 8px;
  }
  .tk-product-quantity {
    align-self: center;
    flex: 0 0 auto;
  }
  .tk-product-quantity > span:first-child {
    display: none;
  }
  .tk-product-quantity-stepper,
  .tk-product-cannabinoids span {
    min-height: 42px;
    display: inline-flex;
    align-items: center;
  }
  .tk-product-quantity-stepper {
    gap: 4px;
    padding: 4px;
  }
  .tk-product-quantity-stepper button {
    width: 30px;
    height: 34px;
  }
  .tk-product-quantity input {
    width: 42px;
    min-height: 38px;
  }
  .tk-product-cannabinoids {
    justify-content: center;
    flex: 0 1 auto;
    flex-wrap: nowrap;
    gap: 6px;
  }
  .tk-product-cannabinoids span {
    padding-inline: 9px;
    white-space: nowrap;
  }
  .tk-product-purchase-row {
    justify-items: center;
  }
  .tk-product-size-picker {
    width: 100%;
    justify-items: center;
  }
  .tk-product-size-picker > div {
    justify-content: center;
  }
  .tk-product-add-cart {
    max-width: min(320px, 88vw);
  }
  .tk-client-confirmation-grid {
    grid-template-columns: 1fr;
  }
  .tk-demo-admin-menu {
    width: min(250px, calc(100vw - 24px));
    bottom: max(78px, env(safe-area-inset-bottom, 0px));
  }
  .tk-product-official-stack {
    top: 12px;
    left: -10px;
    right: auto;
    gap: 7px;
    width: min(74px, 21vw);
  }
  .tk-product-official-stack button {
    min-height: 58px;
    border: 1px solid rgba(255,255,255,0.24);
    border-radius: 12px;
  }
  .tk-product-official-stack button[data-active="true"] {
    background:
      radial-gradient(circle at 66% 28%, rgba(255,255,255,0.48), transparent 26%),
      linear-gradient(145deg, rgba(31,90,52,0.98), rgba(9,30,18,0.98));
    color: transparent;
  }
  .tk-product-left-rail .tk-product-image-row[data-source="official"] {
    display: none;
  }
  .tk-product-image-carousel { grid-auto-columns: minmax(132px, 72%); }
  .tk-scroll-top {
    left: auto;
    right: var(--tk-scroll-top-right-mobile, 126px);
    bottom: var(--tk-scroll-top-bottom-mobile, 86px);
    width: 42px;
    height: 42px;
    transform: translateY(0);
  }
  .tk-scroll-top:hover {
    transform: translateY(-2px);
  }
}

@media (max-width: 560px) {
  .tk-row {
    --tk-row-card-basis-active: var(--tk-row-card-basis-mobile, calc((100% - 24px) / 3));
  }
  .tk-in-page-ad-placement,
  .tk-homepage-inserted-content {
    --tk-ad-grid-columns-active: var(--tk-ad-grid-columns-mobile, 1fr);
  }
  /* Founder LIVE EDIT BLOCK 2026-05-01 (mobile 2-column ads = compact
     desktop-style rectangles): when an ad/article row is rendered at
     2+ columns on mobile (data-tk-homepage-columns="2" or "3"), each
     card switches from the wide horizontal desktop layout (88px image
     + copy + CTA in 3 columns) to a compact vertical stack (image
     on top with rectangular aspect, compact title beneath, small CTA).
     Cards stay inside the viewport, gap stays equal, text clamps so
     card height doesn't blow up. The 1-column case keeps the existing
     wider mobile card style. */
  [data-tk-homepage-columns="2"] .tk-in-page-ad-card,
  [data-tk-homepage-columns="3"] .tk-in-page-ad-card {
    /* Founder LIVE EDIT BLOCK 2026-05-01 (mobile 2-col total row height
       must match red-rectangle target — compact, not tall): smaller
       padding and border-radius, image switched from 16:10 (tall) to
       16:7 (compact wide rectangle), title font dropped slightly so
       the whole card lands at ~140-160px instead of 220+. */
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto auto auto;
    align-items: stretch;
    gap: 4px;
    min-height: 0;
    padding: 6px;
    border-radius: 10px;
  }
  [data-tk-homepage-columns="2"] .tk-in-page-ad-media,
  [data-tk-homepage-columns="3"] .tk-in-page-ad-media {
    aspect-ratio: 16 / 7;
    width: 100%;
    border-radius: 7px;
  }
  [data-tk-homepage-columns="2"] .tk-in-page-ad-copy,
  [data-tk-homepage-columns="3"] .tk-in-page-ad-copy {
    gap: 2px;
    min-width: 0;
  }
  [data-tk-homepage-columns="2"] .tk-in-page-ad-copy small,
  [data-tk-homepage-columns="3"] .tk-in-page-ad-copy small {
    font-size: 9px;
    letter-spacing: .1em;
  }
  [data-tk-homepage-columns="2"] .tk-in-page-ad-copy strong,
  [data-tk-homepage-columns="3"] .tk-in-page-ad-copy strong {
    font-size: 13px;
    line-height: 1.15;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  [data-tk-homepage-columns="2"] .tk-in-page-ad-copy em,
  [data-tk-homepage-columns="3"] .tk-in-page-ad-copy em {
    font-size: 10px;
    display: -webkit-box;
    -webkit-line-clamp: 1;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  [data-tk-homepage-columns="2"] .tk-in-page-ad-cta,
  [data-tk-homepage-columns="3"] .tk-in-page-ad-cta {
    justify-self: start;
    padding: 5px 10px;
    font-size: 11px;
  }
  .tk-header-row {
    row-gap: 0;
    column-gap: 8px;
  }
  .tk-logo-word {
    font-size: 16px;
  }
  .tk-pill-cart {
    padding: 0;
    width: 38px;
    height: 38px;
    justify-content: center;
    box-shadow: none;
    border-color: transparent;
    background: transparent;
  }
  .tk-cart-count {
    position: absolute;
    top: 1px;
    right: -2px;
  }
  .tk-notifications-popover {
    /* Founder live edit 2026-04-29 + LIVE EDIT BLOCK 2026-04-30 (item 1 —
       activity center mobile fix): on mobile the activity bubble must
       NEVER exceed phone width and must not hang off-screen. We pin the
       right edge to a small inset (12px), constrain width to a viewport-
       relative cap (calc(100vw - 24px)), and let the popover fall directly
       under the activity icon by anchoring it via right + top instead of
       absolute pixel offsets that could misalign at narrow widths. The
       lightning-bolt icon, theme-green Toke Bucks emphasis, and friend/
       referral controls are unchanged — only the bubble geometry is
       fixed here. */
    position: absolute;
    right: var(--tk-notifications-right-mobile, 12px);
    left: auto;
    top: calc(100% + var(--tk-notifications-top-offset, 6px));
    width: var(--tk-notifications-width-mobile, calc(100vw - 24px));
    max-width: var(--tk-notifications-max-width-mobile, calc(100vw - 24px));
    max-height: var(--tk-notifications-max-height-mobile, calc(100dvh - 140px));
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .tk-notification-tokebucks-ledger,
  .tk-notification-friends,
  .tk-notification-referrals {
    /* Founder LIVE EDIT BLOCK 2026-04-30 (item 1): inner blocks constrained
       so long values do not push the bubble wider than the viewport. */
    width: 100%;
    min-width: 0;
  }
  .tk-notification-tokebucks-ledger strong,
  .tk-notification-tokebucks-ledger h3,
  .tk-notification-friends h3,
  .tk-notification-referrals h3 {
    color: var(--tk-leaf);
  }
  .tk-cart-drawer {
    top: auto;
    bottom: 0;
    width: 100vw;
    height: min(68dvh, 560px);
    border-radius: 24px 24px 0 0;
    border-left: 0;
    border-top: 1px solid var(--tk-line);
    transform: translateY(104%);
  }
  body.tk-cart-open .tk-cart-drawer { transform: translateY(0); }
  body.tk-cart-open { overflow: hidden; overscroll-behavior: none; }
  .tk-cart-buttons {
    grid-template-columns: 1fr;
  }
  .tk-row-head {
    grid-template-columns: 1fr auto;
  }
  .tk-row-sub {
    grid-column: 1 / -1;
  }
  .tk-location-picker {
    /* Founder LIVE EDIT 2026-05-01 (vertically center the location
       picker on mobile): the prior align-items: stretch broke the
       base rule's place-items: center on mobile — the card was
       pinned to the top edge with stretch height. align-items:
       center restores vertical centering so the modal sits in the
       middle of the viewport regardless of card height. */
    align-items: center;
    padding: 10px;
  }
  .tk-location-card {
    max-height: min(90dvh, calc(var(--visual-vh, 1vh) * 90));
    padding: 16px;
  }
  .tk-location-cities {
    max-height: min(310px, 42svh);
  }
}

/* =============== HOMEPAGE SHOP-BY-CATEGORY RAIL =================
   Founder Pass 10.6 2026-05-03 — homepage category square viewer.
   Founder rule: clean modern soft tiles, no-caps labels, very good
   icons. Theme tokens drive colour so TikToke (green) and Netbics
   (red) brand swap recolour cleanly. Light bg, not dark. */
.tk-shop-by-category {
  /* Founder Pass 10.6.x 2026-05-04 — match every other homepage
     carousel. .tk-row uses width: var(--tk-content-width) + margin-
     left/right: auto, which centers the entire row block on the
     page. Apply the SAME rule here. No custom padding-inline math,
     no JS scroll trick, no justify-content override. The track
     inside flows naturally inside this content-width parent. */
  display: grid;
  gap: 12px;
  width: var(--tk-content-width);
  margin-left: auto;
  margin-right: auto;
  margin-top: clamp(28px, 4vw, 44px);
  margin-bottom: 18px;
}
.tk-shop-by-category-heading {
  margin: 0;
  font-size: clamp(20px, 2.4vw, 26px);
  font-weight: 800;
  letter-spacing: -0.02em;
  color: var(--tk-leaf-deep);
  text-transform: lowercase;
  /* Founder HARD CORRECTION 2026-05-04 — founder rule: "make the
     shop by category centered". Heading centers above the rail. */
  text-align: center;
}
/* Founder HARD CORRECTION 2026-05-04 — founder rule (verbatim):
   "make the 'shop by category' a 1 - row carousel on all devices".
   Was a responsive 5/4/3-column grid that wrapped to multiple rows.
   Now a single-row horizontal-scroll track on every viewport. Tile
   width comes from --tk-shop-tile-size with mobile/desktop variants
   so the rail still feels right at narrow + wide widths. */
.tk-shop-by-category-grid {
  display: flex;
  flex-wrap: nowrap;
  gap: 10px;
  overflow-x: auto;
  overflow-y: visible;
  scroll-snap-type: x proximity;
  scrollbar-width: thin;
  padding-bottom: 4px;
  /* Founder Pass 10.6.x 2026-05-04 — match every other homepage
     carousel: the parent .tk-shop-by-category is now content-width
     with margin: 0 auto (same rule as .tk-row), so this track flows
     naturally inside that centered parent. No custom padding-inline,
     no justify-content override. */
}
.tk-shop-by-category-grid::-webkit-scrollbar { height: 6px; }
.tk-shop-by-category-grid::-webkit-scrollbar-thumb { background: var(--tk-line-strong); border-radius: 999px; }
@media (max-width: 720px) {
  .tk-shop-by-category-grid {
    gap: 8px;
    /* Founder HARD CORRECTION 2026-05-04 — founder rule (verbatim):
       "mobile 'shop by category' carousel is sstill NOT centered to
       the page. fix it". On phones the row overflows so safe-center
       falls back to start-alignment, making the rail read as
       left-anchored. Pad the track inline-start/end by half the
       remaining viewport so the first tile lands centered in the
       viewport at scroll=0, and snap-align: center keeps each tile
       centered as the user swipes. */
    /* Founder Pass 10.6.x 2026-05-04 — founder rule (verbatim):
       "on mobile shop by category carousel, flower starts from
       halfway in the page (it still scrolls over, but make it so
       the first 3 categories are visible)" + "un-center 'shop by
       category' on mobiles!!! JUST THE CATEGORY CAROUSEL IS
       SUPPOSED TO BE CENTERED!!! AND ON DESKTOP ONLY!!!!!". Mobile
       gets a fixed 16px gutter so Flower starts at the page edge
       and 3 tiles are visible. snap-align: start so swipe-end
       snaps the next tile to the left edge. justify-content
       overridden to flex-start so safe-center never kicks in on
       mobile. Heading text-align flipped from center to left. */
    padding-inline: 16px;
    scroll-padding-inline: 16px;
    justify-content: flex-start;
  }
  .tk-shop-by-category-heading {
    text-align: left;
  }
  .tk-shop-by-category-tile {
    scroll-snap-align: start;
  }
}
.tk-shop-by-category-tile {
  position: relative;
  display: grid;
  grid-template-rows: 1fr auto;
  align-items: center;
  justify-items: center;
  gap: 8px;
  flex: 0 0 var(--tk-shop-tile-size, 168px);
  width: var(--tk-shop-tile-size, 168px);
  aspect-ratio: 1 / 1;
  scroll-snap-align: start;
  padding: 10px;
  border-radius: 18px;
  background: color-mix(in srgb, var(--tk-leaf) 7%, var(--tk-paper));
  border: 1px solid color-mix(in srgb, var(--tk-leaf) 14%, transparent);
  color: var(--tk-leaf-deep);
  text-decoration: none;
  font-weight: 700;
  font-size: clamp(11px, 1.2vw, 13px);
  letter-spacing: 0.01em;
  cursor: pointer;
  transition: transform .14s ease, background .14s ease, border-color .14s ease, box-shadow .14s ease;
}
.tk-shop-by-category-tile:hover,
.tk-shop-by-category-tile:focus-visible {
  background: color-mix(in srgb, var(--tk-leaf) 14%, var(--tk-paper));
  border-color: color-mix(in srgb, var(--tk-leaf) 32%, transparent);
  transform: translateY(-2px);
  box-shadow: 0 12px 24px color-mix(in srgb, var(--tk-leaf-deep) 10%, transparent);
}
.tk-shop-by-category-icon {
  display: grid;
  place-items: center;
  width: 56%;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  background: color-mix(in srgb, var(--tk-leaf) 16%, var(--tk-paper));
  color: var(--tk-leaf-deep);
}
.tk-shop-by-category-icon svg {
  width: 56%;
  height: 56%;
}
.tk-shop-by-category-label {
  text-transform: lowercase;
  text-align: center;
  line-height: 1.1;
}
/* Founder HARD CORRECTION 2026-05-04 — tile size variants for the
   1-row carousel. On phones the tile shrinks so 3-4 still peek
   visibly and the user can scroll for the rest. */
:root { --tk-shop-tile-size: 168px; }
@media (max-width: 1100px) { :root { --tk-shop-tile-size: 152px; } }
@media (max-width: 720px)  { :root { --tk-shop-tile-size: 124px; } }
@media (max-width: 430px)  { :root { --tk-shop-tile-size: 108px; } }

/* =============== ATTRIBUTE INFO POPUP ===========================
   Founder Pass 10.6 — clickable effect/use/time-of-day chips open a
   shared lightweight popup positioned ~50px above the Tokebot button.
   Same family as Tokebot popup but NO background blur (founder rule).
   Light theme tokens; respects brand swap. */
.tk-attr-popup-backdrop {
  position: fixed;
  inset: 0;
  z-index: 110;
  background: transparent;
  pointer-events: auto;
}
.tk-attr-popup {
  position: fixed;
  right: clamp(16px, 4vw, 32px);
  bottom: calc(var(--tk-tokebot-bottom-offset, 84px) + 50px);
  z-index: 120;
  width: min(360px, calc(100vw - 32px));
  max-height: 33vh;
  overflow-y: auto;
  background: var(--tk-paper);
  color: var(--tk-ink);
  border: 1px solid color-mix(in srgb, var(--tk-leaf) 22%, transparent);
  border-radius: 18px;
  box-shadow: 0 24px 60px color-mix(in srgb, var(--tk-leaf-deep) 22%, transparent);
  padding: 16px 16px 14px;
  font-size: 13px;
  line-height: 1.4;
}
.tk-attr-popup-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 8px;
}
.tk-attr-popup-title {
  margin: 0;
  font-size: 15px;
  font-weight: 800;
  color: var(--tk-leaf-deep);
  text-transform: lowercase;
  flex: 1;
}
.tk-attr-popup-close {
  width: 26px;
  height: 26px;
  border: 0;
  border-radius: 999px;
  background: color-mix(in srgb, var(--tk-leaf) 8%, transparent);
  color: var(--tk-leaf-deep);
  font-size: 16px;
  font-weight: 800;
  cursor: pointer;
  line-height: 1;
}
.tk-attr-popup-close:hover { background: color-mix(in srgb, var(--tk-leaf) 18%, transparent); }
.tk-attr-popup-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0 0 10px;
  font-size: 11px;
  color: var(--tk-muted);
}
.tk-attr-popup-meta-pill {
  display: inline-flex;
  align-items: center;
  padding: 2px 8px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--tk-leaf) 10%, transparent);
  color: var(--tk-leaf-deep);
  font-weight: 700;
  text-transform: lowercase;
}
.tk-attr-popup-meta-pill[data-from="leafly"]      { background: color-mix(in srgb, var(--tk-warm) 14%, transparent); color: var(--tk-leaf-deep); }
.tk-attr-popup-meta-pill[data-from="leafythings"] { background: color-mix(in srgb, var(--tk-leaf) 16%, transparent); color: var(--tk-leaf-deep); }
.tk-attr-popup-meta-pill[data-from="aiResearch"]  { background: color-mix(in srgb, var(--tk-leaf-deep) 12%, transparent); color: var(--tk-leaf-deep); }
.tk-attr-popup-body { margin: 0; }
.tk-attr-popup-sources {
  margin: 8px 0 0;
  padding: 8px 0 0;
  border-top: 1px solid color-mix(in srgb, var(--tk-leaf) 12%, transparent);
  font-size: 11px;
  display: grid;
  gap: 4px;
}
.tk-attr-popup-sources a { color: var(--tk-leaf-deep); text-decoration: underline; }

/* Light-theme attribute chips — replaces the prior dark pill look on
   product detail effect/use/time-of-day rows. The wrapper class
   .tk-product-attr-chips ensures we don't bleed into other contexts. */
.tk-product-attr-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 6px 0;
}
.tk-product-attr-chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 5px 12px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--tk-leaf) 10%, var(--tk-paper));
  color: var(--tk-leaf-deep);
  border: 1px solid color-mix(in srgb, var(--tk-leaf) 18%, transparent);
  font-size: 12px;
  font-weight: 700;
  text-transform: lowercase;
  cursor: pointer;
  transition: background .14s ease, border-color .14s ease, transform .14s ease;
}
.tk-product-attr-chip:hover,
.tk-product-attr-chip:focus-visible {
  background: color-mix(in srgb, var(--tk-leaf) 18%, var(--tk-paper));
  border-color: color-mix(in srgb, var(--tk-leaf) 38%, transparent);
  transform: translateY(-1px);
}
.tk-product-attr-chip[data-attr-type="negativeEffect"] {
  background: color-mix(in srgb, var(--tk-warm) 12%, var(--tk-paper));
  border-color: color-mix(in srgb, var(--tk-warm) 22%, transparent);
  color: color-mix(in srgb, var(--tk-warm) 65%, var(--tk-ink));
}
.tk-product-attr-chip[data-researched-by-ai="true"]::after {
  content: "ai";
  margin-left: 4px;
  padding: 0 5px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--tk-leaf-deep) 14%, transparent);
  color: var(--tk-leaf-deep);
  font-size: 9px;
  font-weight: 800;
  letter-spacing: 0.04em;
}

/* Founder HARD CORRECTION 2026-05-04 — founder rule (verbatim):
   "on order previews on mobile--move everything down the page
   (under the menu) 50px". The /orders/* mobile view sits flush
   under the fixed header; founder wants 50px of breathing room
   below the menu before the order content starts. Adds to the
   existing mobile body.tk-page padding-top (which already accounts
   for the header height + banner). */
@media (max-width: 720px) {
  body.tk-order-page.tk-page {
    padding-top: calc(
      var(--tk-legal-banner-mobile-h, 0px)
      + var(--tk-mobile-header-height, 124px)
      + env(safe-area-inset-top, 0px)
      + 150px
    );
    scroll-padding-top: calc(
      var(--tk-legal-banner-mobile-h, 0px)
      + var(--tk-mobile-header-height, 124px)
      + env(safe-area-inset-top, 0px)
      + 150px
    );
  }
}
