/* ════════════════════════════════════════════════════════════════════════
   TOMODATCHI SHOP — core styles
   Ported from the main tomodatchi.net character-directory design system.
   ════════════════════════════════════════════════════════════════════════ */

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

:root {
  --bg: #ffffff;
  --grid: rgba(148,179,215,0.18);
  --ink: #2e37fb;
  --muted: #9099ac;
  --border: #c8d8ec;
  --border-soft: #e8f0f9;
  --card-border: 4px;
  --card-border-outer: 8px;
  --radius: 24px;
  --nav-h: 72px;
  --logo-blue: #2e37fb;

  --card-art-height: 200px;
  --card-img-maxheight: 160px;
  --card-img-hover-scale: 1.14;

  /* Site palette — pale grey-blue replaces the 5-colour card system */
  --card-bg: #eaf4fd;
  --card-shade: #d4e8f5;

  /* 5-colour palette kept for reference/other uses */
  --c-pink:   #ffa1bc; --c-pink-shade:   #dc86b9;
  --c-amber:  #ffd39e; --c-amber-shade:  #edbe9f;
  --c-green:  #affcbd; --c-green-shade:  #91cfbd;
  --c-blue:   #9cd8f7; --c-blue-shade:   #8dc1f0;
  --c-purple: #c3a6ff; --c-purple-shade: #9f88f5;
}

html {
  scroll-behavior: smooth;
  /* Safety net: stops any single element that slightly exceeds 100vw
     (the animating search input, the fixed-position nav bar, etc) from
     stretching the page's real horizontal scroll width. Without this,
     content that's correctly width:100% can still get visually
     clipped at the right edge on mobile because "100%" ends up
     measured against a wider, overflowed canvas instead of the actual
     viewport. */
  overflow-x: hidden;
  width: 100%;
}

body.tomo-theme {
  font-family: 'Nunito', sans-serif;
  background-color: var(--bg);
  background-image:
    linear-gradient(var(--grid) 1px, transparent 1px),
    linear-gradient(90deg, var(--grid) 1px, transparent 1px);
  background-size: 56px 56px;
  color: var(--ink);
  min-height: 100vh;
  margin: 0;
  padding-top: var(--nav-h);
  /* Same safety net as html above. */
  overflow-x: hidden;
  width: 100%;
}

img { max-width: 100%; height: auto; }
a { color: inherit; }
ul { list-style: none; margin: 0; padding: 0; }

.screen-reader-text {
  position: absolute !important;
  width: 1px; height: 1px; overflow: hidden;
  clip: rect(1px,1px,1px,1px);
}

/* ─── NAV ───
   The bar's background/blur/border live on ::before instead of directly
   on .tomo-nav, as a separate paint layer with its own z-index. This is
   what lets the logo's grey outline (z-index 0) sit BEHIND this layer
   while the white outline + logo artwork (z-index 2) sit IN FRONT of it —
   true layered-paper depth, not just a visual approximation. */
.tomo-nav {
  position: fixed; top: 0; left: 0; width: 100%; z-index: 9999;
  display: grid;
  /* Logo column is fixed width, center grows, right is fixed */
  grid-template-columns: auto 1fr auto;
  align-items: center;
  padding: 0 24px;
  height: var(--nav-h);
  gap: 16px;
  overflow: visible;
}

.tomo-nav::before {
  content: "";
  position: absolute;
  top: 0; left: 0; right: 0;
  height: var(--nav-h);
  background: rgba(255,255,255,0.93);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  /* Was 2px literal, displaying at ~4px on the actual device (2x
     ratio, likely device pixel ratio scaling). Doubled to 4px literal
     to land on the requested 8px displayed, per the same ratio. */
  border-bottom: 4px solid var(--border);
  z-index: 1;
  pointer-events: none;
}

.tomo-nav-left {
  display: flex; align-items: flex-end; min-width: 0;
  align-self: end;
  /* Never shrink — logo always full size */
  flex-shrink: 0;
  /* Deliberately NOT position:relative / z-index here — that would trap
     .tomo-logo-wrap (and its ::before grey-ring pseudo, and the
     .custom-logo-link white-ring/art layer) in its own stacking
     context and break the layering against .tomo-nav::before (the bar
     background). Those z-indexes need to compare directly against the
     bar's z-index, not against a sub-context rooted here. */
}

.tomo-nav-center {
  display: flex; align-items: center; justify-content: center;
  /* Pinned to the visible nav-h band (not row-height centering) — the
     logo's 115px content box (35px margin-top + 80px height) is taller
     than --nav-h and was stretching the grid row itself, which dragged
     align-self:center siblings down below the painted 72px bar at full
     width. height+align-self:start locks this to the real bar height
     regardless of how tall the logo's box grows. Mobile/wrapped layout
     (max-width:780px) overrides grid-row placement separately below and
     is unaffected. */
  height: var(--nav-h);
  align-self: start;
  /* Allow links to scroll horizontally rather than squash */
  min-width: 0;
  overflow: hidden;
  position: relative;
  z-index: 2;
}

.tomo-nav-right {
  display: flex; align-items: center; justify-content: flex-end;
  gap: 12px; min-width: 0;
  /* Same fix as .tomo-nav-center above — pin to the real bar height
     instead of row-height centering, so search/cart stay vertically
     centered in the visible 72px bar instead of the taller implicit
     grid row caused by the logo's overflow. */
  height: var(--nav-h);
  align-self: start;
  flex-shrink: 0;
  position: relative;
  z-index: 2;
}

.tomo-nav-links {
  display: flex; gap: 2px;
  /* Scroll horizontally when space is tight — no visible scrollbar */
  overflow-x: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
  flex-wrap: nowrap;
  /* Don't let links shrink or wrap — scroll instead */
  white-space: nowrap;
}
.tomo-nav-links::-webkit-scrollbar { display: none; }

.tomo-nav-mobile-links { display: none; }

/* When the viewport is narrow enough that links genuinely can't show
   (below ~780px), drop them into a second row below the bar */
@media (max-width: 780px) {
  .tomo-nav {
    padding: 0 16px;
    /* Two rows: top row (logo + burger) + lower row (links + search/cart).
       Row 1 is "auto" (not a hard var(--nav-h)) so it sizes to fit the
       logo exactly like desktop's implicit single row does — a fixed
       72px track would clip the logo's natural overflow above the bar
       and push it upward off-screen. The *visual* 72px bar height still
       comes from .tomo-nav::before below; this is just the grid track. */
    /* Column 1 (logo) uses minmax(0, auto) instead of bare auto — a
       bare auto grid track has the same "won't shrink below content's
       natural width" floor that caused the carousel urlbar bug fixed
       earlier in this project. Without the minmax(0, ...) floor here,
       this column refused to shrink below the logo's full natural
       width no matter what flex-shrink/max-width rules were set on
       the logo itself, since those only affect flex layout — they
       have no power over a CSS Grid track's own sizing algorithm.
       This is why the logo kept cropping even after last round's
       max-width:calc() fix was already in place. */
    grid-template-columns: minmax(0, auto) 1fr auto;
    grid-template-rows: auto auto;
    height: auto;
    /* position: fixed is inherited from the base rule above — fixed
       already establishes a positioning context for the ::before/::after
       panels below, so this must NOT be overridden to relative/static
       or the whole bar stops staying pinned on scroll. */
  }
  .tomo-nav-center {
    /* Links take the flexible left portion of the second row */
    grid-column: 1 / 3;
    grid-row: 2;
    justify-content: flex-start;
    overflow-x: auto;
    border-top: 1px solid var(--border-soft);
    padding: 8px 0 10px 0;
    min-width: 0;
    /* Undo the desktop-only height:var(--nav-h)/align-self:start pin
       above — row 2 here is a natural auto-height row and must stay
       exactly as it was (this is the layout you said is already
       perfect and must not change). */
    height: auto;
    align-self: auto;
  }
  .tomo-nav-left  {
    grid-column: 1;
    grid-row: 1;
    /* Row 1 is auto-sized to fit the logo (see note on .tomo-nav above),
       same as desktop's implicit row — so the logo sits at the exact
       same vertical position in both states and never jumps. */
    align-self: end;
  }
  .tomo-nav-right {
    /* Search + cart move down into the second row, right-aligned
       next to the links */
    grid-column: 3;
    grid-row: 2;
    flex-shrink: 0;
    border-top: 1px solid var(--border-soft);
    padding: 8px 0 10px;
    /* Same revert as .tomo-nav-center above — keep wrapped layout
       untouched. */
    height: auto;
    align-self: auto;
  }
  /* Logo: scale to fit the available width on mobile instead of
     clipping. Desktop's flex-shrink:0 / max-width:none "never squash"
     rules are deliberately left untouched (that's still correct for
     desktop) — this ONLY applies inside the 780px breakpoint, and only
     loosens the hard "never shrink" constraint, it doesn't force a
     smaller size if the logo already fits.
     calc() reasoning: 100vw minus the bar's left+right padding (16px
     each = 32px), minus the burger button's box (38px) and its gap
     from the logo (16px, the .tomo-nav gap value) = the real width
     budget left for the logo. height:auto keeps proportions intact
     (no squashing/distortion) — only the rendered size shrinks. */
  .tomo-logo-wrap,
  .tomo-nav-left {
    flex-shrink: 1;
    min-width: 0;
  }
  .tomo-logo-wrap .custom-logo-link .custom-logo,
  .tomo-logo-wrap .custom-logo-link img,
  .tomo-logo-wrap img {
    max-width: calc(100vw - 32px - 38px - 16px);
    width: auto;
    height: auto;
    /* Cap height so it can't render larger than the desktop 80px even
       on a wide phone in landscape, but allow it to shrink below that
       on narrow screens via the max-width constraint above. */
    max-height: 80px;
  }
  /* Body padding accounts for the taller nav. Bumped from 54px — the
     previous value was clipping page content under row 2 on real
     devices. If this still clips on yours, the number after
     "var(--nav-h) +" is the one to nudge further. */
  body.tomo-theme { padding-top: calc(var(--nav-h) + 76px); }
}

@media (min-width: 781px) {
  body.tomo-theme { padding-top: var(--nav-h); }
  .tomo-nav-burger { display: none !important; }
  .tomo-nav-mobile-links { display: none !important; }
}
/* ─────────────────────────────────────────────────────────────────────
   LOGO — the_custom_logo() outputs:
     <a class="custom-logo-link" href="/"><img class="custom-logo" …></a>
   inside <div class="tomo-logo-wrap">.

   The white ring + visible artwork render on the real <img> itself,
   sitting ABOVE the bar (z-index 2, inside .tomo-logo-wrap's stacking
   context, which is itself part of the normal page flow now — no
   longer forced to z-index 10000 on the wrapper, since only specific
   children need to be elevated, not the whole wrapper).

   The grey ring renders on a SEPARATE element — a ::before pseudo on
   .tomo-logo-wrap — duplicating the same logo image via
   background-image, with ONLY the grey-ring drop-shadow filter
   applied, sized to exactly match the real <img> via absolute
   positioning + inset:0. This pseudo sits at z-index 0, BELOW
   .tomo-nav::before (z-index 1, the bar's own white background), so
   the grey ring tucks behind the topbar — creating the illusion that
   the bar's own border continues into/behind the logo's outline,
   exactly as requested.

   This split was necessary because drop-shadow() filters paint as
   part of the SAME element they're applied to — a single <img> cannot
   have part of its filter stack behind one layer and part above
   another. Splitting the grey ring onto its own pseudo-element is the
   only way to give it independent stacking from the white ring/art.
   ───────────────────────────────────────────────────────────────────── */
.tomo-logo-wrap {
  display: flex;
  align-items: flex-end;
  position: relative;
  /* Standard position, +15px lower per request (20px -> 35px) */
  margin-top: 35px;
  /* Extra squash protection alongside .tomo-nav-left's flex-shrink:0 */
  flex-shrink: 0;
}

/* Grey ring — duplicate of the logo image, grey-ring filter only,
   sitting BEHIND the bar's background (.tomo-nav::before is z-index 1).
   Sized via inset:0 to exactly match the real <img>'s rendered box,
   so it tracks any responsive/mobile resizing automatically without
   needing to know the image's native pixel dimensions. */
.tomo-logo-wrap::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image: url('https://shop.tomodatchi.net/wp-content/uploads/2025/03/tomodatchilogoo2-scaled.png');
  background-repeat: no-repeat;
  background-position: left bottom;
  background-size: contain;
  filter:
    /* grey ring — radius recalculated from real on-screen measurement.
       6px literal was displaying at ~14px on the actual device (2.33x
       ratio). Target was 8px displayed, so: 8 / (14/6) = 3.43px new
       literal radius. Diagonal component = 3.43 * cos(45deg) = 2.42px.
       Still 0px blur. */
    drop-shadow(3.43px  0.00px 0px #c8d8ec)
    drop-shadow(2.42px  2.42px 0px #c8d8ec)
    drop-shadow(0.00px  3.43px 0px #c8d8ec)
    drop-shadow(-2.42px  2.42px 0px #c8d8ec)
    drop-shadow(-3.43px  0.00px 0px #c8d8ec)
    drop-shadow(-2.42px -2.42px 0px #c8d8ec)
    drop-shadow(0.00px -3.43px 0px #c8d8ec)
    drop-shadow(2.42px -2.42px 0px #c8d8ec);
}

/* WP's generated anchor — clean block, no inline gap */
.tomo-logo-wrap .custom-logo-link {
  display: block;
  line-height: 0;
  text-decoration: none;
  position: relative;
  /* Above .tomo-nav (z-index 9999) and the bar's background — this is
     the layer that now needs the high z-index, not the whole wrapper,
     since the grey-ring pseudo above deliberately stays low. */
  z-index: 10000;
}

/* The img itself — white ring only now (grey ring moved to the
   ::before pseudo above). An 8-point true-circle ring (equal radius
   at every angle) with a touch of antialiasing blur bridges the gaps
   between points so the edge reads as one solid stroke. */
.tomo-logo-wrap .custom-logo-link .custom-logo,
.tomo-logo-wrap .custom-logo-link img,
.tomo-logo-wrap img {
  display: block;
  height: 80px;
  width: auto;
  /* Override the global `img { max-width:100% }` reset and guarantee
     the logo never compresses horizontally at any viewport width. */
  max-width: none;
  flex-shrink: 0;
  position: relative;
  z-index: 2;
  filter:
    /* white ring — radius 3px, blur cut from 0.4px to 0.1px (antialias-
       level only, just enough to bridge the 8 discrete shadow points
       into one stroke without a visible soft/fuzzy halo) */
    drop-shadow(3.00px  0.00px 0.1px #ffffff)
    drop-shadow(2.12px  2.12px 0.1px #ffffff)
    drop-shadow(0.00px  3.00px 0.1px #ffffff)
    drop-shadow(-2.12px  2.12px 0.1px #ffffff)
    drop-shadow(-3.00px  0.00px 0.1px #ffffff)
    drop-shadow(-2.12px -2.12px 0.1px #ffffff)
    drop-shadow(0.00px -3.00px 0.1px #ffffff)
    drop-shadow(2.12px -2.12px 0.1px #ffffff);
}

.tomo-logo-text-link { text-decoration: none; }
.tomo-logo-text {
  font-family: 'Fredoka', sans-serif; font-weight: 700; font-size: 1.05rem;
  color: var(--ink);
}

.tomo-nav-links { display: flex; gap: 2px; }
.tomo-nav-links a {
  font-family: 'Fredoka', sans-serif; font-size: 0.95rem; font-weight: 500;
  text-decoration: none; color: var(--muted);
  padding: 5px 14px; border-radius: 100px;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
  display: inline-block;
  /* Idle state: white rounded pill, same shape/radius as the active
     blue pill below, with a faint border so it reads against the
     bar's own near-white background instead of disappearing into it. */
  background: #ffffff;
  border: 2px solid var(--border-soft);
}
.tomo-nav-links a:hover { background: var(--border-soft); color: var(--ink); }
.tomo-nav-links li.current-menu-item > a,
.tomo-nav-links a.active { background: var(--ink); color: #fff; }

/* Search — deep blue rounded button */
.tomo-nav-search { position: relative; display: flex; align-items: center; }
.tomo-nav-search input[type="search"] {
  font-family: 'Nunito', sans-serif; font-size: 0.85rem;
  width: 0; opacity: 0; padding: 0; border: none;
  background: var(--border-soft); border-radius: 100px;
  transition: width 0.25s ease, opacity 0.2s ease, padding 0.25s ease;
  height: 34px;
}
.tomo-nav-search.open input[type="search"] {
  width: 160px; opacity: 1; padding: 0 14px;
}
.tomo-nav-search button {
  width: 34px; height: 34px; border-radius: 50%; flex-shrink: 0;
  border: 2px solid var(--ink); background: var(--ink); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  color: #fff; transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.tomo-nav-search button:hover { background: #1c24d9; border-color: #1c24d9; }

/* Cart pill */
.tomo-cart-link {
  display: flex; align-items: center; gap: 7px;
  font-family: 'Fredoka', sans-serif; font-size: 0.85rem; font-weight: 600;
  background: var(--border-soft); border: 2px solid var(--border);
  border-radius: 100px; padding: 5px 14px 5px 10px;
  text-decoration: none; color: var(--ink);
  transition: background 0.15s, border-color 0.15s, transform 0.15s;
}
.tomo-cart-link:hover { background: var(--ink); color: #fff; border-color: var(--ink); transform: scale(1.04); }
.tomo-cart-icon { width: 18px; height: 18px; flex-shrink: 0; }
.tomo-cart-count {
  background: var(--ink); color: #fff;
  font-size: 0.68rem; font-weight: 700;
  min-width: 16px; height: 16px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0 2px;
}
.tomo-cart-link:hover .tomo-cart-count { background: #fff; color: var(--ink); }

/* Lang toggle */
.lang-toggle {
  display: flex; align-items: center;
  background: var(--border-soft); border: 2px solid var(--border);
  border-radius: 100px; padding: 3px; gap: 0;
}
.lang-btn {
  font-family: 'Fredoka', sans-serif; font-size: 0.72rem; font-weight: 600;
  padding: 3px 10px; border-radius: 100px; border: none;
  background: transparent; cursor: pointer; color: var(--muted);
  transition: background 0.14s, color 0.14s; line-height: 1;
}
.lang-btn.active { background: var(--ink); color: #fff; }

/* Mobile nav toggle */
.tomo-nav-burger {
  display: none; width: 38px; height: 38px; border-radius: 50%;
  border: 2px solid var(--border); background: #fff; cursor: pointer;
  align-items: center; justify-content: center; color: var(--ink);
}

/* ─── PAGE WRAPPER ─── */
.tomo-shop-wrap {
  width: 100%;
  padding: 40px 36px 80px;
  max-width: 1400px;
  margin: 0 auto;
  /* Same class of fix as .tomo-browser-urlbar above — without this,
     a descendant's content (like the carousel's urlbar text) can
     force this wrapper, and therefore the whole page, wider than the
     viewport. box-sizing:border-box (set globally via the *,*::before
     rule near the top of this file) means padding is included in
     width:100%, so this stays exact at any viewport size. */
  overflow-x: hidden;
}
.tomo-shop-inner { width: 100%; }

.tomo-shop-layout {
  display: grid;
  /* minmax(0, ...) is the CSS Grid equivalent of flexbox's min-width:0
     fix used on .tomo-browser-urlbar — grid tracks have the exact same
     "won't shrink below content's natural width" default. Without the
     0 floor here, the 300px sidebar column (which contains the
     carousel) could still drag the 1fr main column wider than
     available space whenever its content's natural width exceeded
     300px, which is exactly what was happening with the urlbar text. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 300px);
  gap: 40px;
  align-items: start;
}
@media (max-width: 1000px) {
  .tomo-shop-layout { grid-template-columns: minmax(0, 1fr); }
}

/* Page heading band */
.tomo-page-head {
  text-align: center;
  padding: 12px 24px 36px;
}
.tomo-page-eyebrow {
  font-family: 'Fredoka', sans-serif; font-size: 0.78rem; font-weight: 500;
  color: var(--muted); letter-spacing: 0.1em; text-transform: uppercase;
  margin: 0 0 6px;
}
.tomo-page-title {
  font-family: 'Fredoka', sans-serif; font-size: 2.2rem; font-weight: 700;
  color: var(--ink); margin: 0;
}

/* ─── FOOTER ─── */
.tomo-footer {
  border-top: 2px solid var(--border-soft);
  padding: 28px 36px 36px;
  text-align: center;
  font-family: 'Fredoka', sans-serif; font-size: 0.8rem; color: var(--muted);
}
.tomo-footer a { text-decoration: none; color: var(--muted); }
.tomo-footer a:hover { color: var(--ink); }
.tomo-footer-links { display: flex; justify-content: center; gap: 18px; margin-bottom: 10px; flex-wrap: wrap; }

/* ─── BUTTONS (shared pill style) ─── */
.tomo-btn {
  font-family: 'Fredoka', sans-serif; font-size: 0.92rem; font-weight: 600;
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  background: var(--ink); color: #fff !important;
  border: 2.5px solid var(--ink); border-radius: 100px;
  padding: 11px 26px; cursor: pointer;
  text-decoration: none !important;
  transition: background 0.15s, color 0.15s, transform 0.15s, box-shadow 0.18s;
  box-shadow: 0 4px 14px rgba(46,55,251,0.18);
}
.tomo-btn:hover { background: #1c24d9; transform: translateY(-1px); box-shadow: 0 8px 22px rgba(46,55,251,0.26); }
.tomo-btn:active { transform: translateY(0); }
.tomo-btn-outline {
  background: #fff; color: var(--ink) !important; border-color: var(--border);
  box-shadow: 0 4px 14px rgba(160,184,210,0.25);
}
.tomo-btn-outline:hover { background: var(--border-soft); border-color: var(--ink); }
.tomo-btn-block { width: 100%; }
.tomo-btn[disabled], .tomo-btn.disabled {
  opacity: 0.5; cursor: not-allowed; transform: none !important;
}

/* Generic blue-bordered "sticker card" panel */
.tomo-panel {
  background: #fff;
  border: var(--card-border-outer) solid var(--logo-blue);
  border-radius: var(--radius);
  box-shadow: 4px 5px 8px rgba(160,184,210,0.45);
  overflow: hidden;
}

/* Animations */
@keyframes fadeUp {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}
.anim { animation: fadeUp 0.42s cubic-bezier(0.22,1,0.36,1) both; }
.anim-d1 { animation-delay: 0.06s; }
.anim-d2 { animation-delay: 0.12s; }
.anim-d3 { animation-delay: 0.18s; }

@keyframes bgDriftStripes {
  from { background-position: 0 0; }
  to   { background-position: -28px 28px; }
}
@keyframes popOutline {
  0%   { filter: none; }
  40%  {
    filter:
      drop-shadow( 0px   3px 0px white) drop-shadow( 0px  -3px 0px white)
      drop-shadow( 3px   0px 0px white) drop-shadow(-3px   0px 0px white)
      drop-shadow( 2px   2px 0px white) drop-shadow(-2px   2px 0px white)
      drop-shadow( 2px  -2px 0px white) drop-shadow(-2px  -2px 0px white)
      drop-shadow(-4px   4px 0px #2e37fb);
  }
  100% {
    filter:
      drop-shadow( 0px   3px 0px white) drop-shadow( 0px  -3px 0px white)
      drop-shadow( 3px   0px 0px white) drop-shadow(-3px   0px 0px white)
      drop-shadow( 2px   2px 0px white) drop-shadow(-2px   2px 0px white)
      drop-shadow( 2px  -2px 0px white) drop-shadow(-2px  -2px 0px white)
      drop-shadow(-4px   4px 0px #2e37fb);
  }
}

/* ─── VARIANT PICKER DIALOGUE (visual novel style) ─── */
.tomo-vn-overlay {
  position: fixed; inset: 0;
  background: rgba(20,24,40,0.35);
  z-index: 19000;
  opacity: 0; pointer-events: none;
  transition: opacity 0.2s ease;
}
.tomo-vn-overlay.open { opacity: 1; pointer-events: all; }

.tomo-vn-panel {
  position: fixed;
  bottom: 40px;
  left: 50%; transform: translateX(-50%) translateY(20px);
  width: min(480px, 92vw);
  background: #fff;
  border: 6px solid var(--logo-blue);
  border-radius: 22px;
  box-shadow: 0 16px 48px rgba(46,55,251,0.22), 4px 5px 8px rgba(160,184,210,0.5);
  padding: 20px 22px 22px;
  z-index: 19001;
  opacity: 0;
  transition: opacity 0.22s ease, transform 0.22s cubic-bezier(0.22,1,0.36,1);
  pointer-events: none;
}
.tomo-vn-overlay.open .tomo-vn-panel {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
  pointer-events: all;
}
.tomo-vn-title {
  font-family: 'Fredoka', sans-serif; font-size: 0.72rem; font-weight: 600;
  color: var(--muted); text-transform: uppercase; letter-spacing: 0.1em;
  margin: 0 0 6px;
}
.tomo-vn-product-name {
  font-family: 'Fredoka', sans-serif; font-size: 1.05rem; font-weight: 700;
  color: var(--logo-blue); margin: 0 0 16px;
}
.tomo-vn-attr-label {
  font-family: 'Fredoka', sans-serif; font-size: 0.72rem; font-weight: 600;
  color: var(--muted); text-transform: uppercase; letter-spacing: 0.07em;
  margin: 0 0 8px;
}
.tomo-vn-choices {
  display: flex; flex-direction: column; gap: 8px;
}
.tomo-vn-choice {
  font-family: 'Fredoka', sans-serif; font-size: 0.95rem; font-weight: 600;
  background: var(--border-soft); border: 2.5px solid var(--border);
  border-radius: 100px; padding: 10px 20px;
  cursor: pointer; color: var(--ink); text-align: left;
  transition: background 0.14s, border-color 0.14s, transform 0.14s;
  display: flex; align-items: center; gap: 10px;
}
.tomo-vn-choice::before {
  content: '▷';
  font-size: 0.75rem; color: var(--muted);
  flex-shrink: 0;
  transition: color 0.14s;
}
.tomo-vn-choice:hover {
  background: var(--ink); color: #fff; border-color: var(--ink);
  transform: translateX(4px);
}
.tomo-vn-choice:hover::before { color: rgba(255,255,255,0.7); }
.tomo-vn-choice.out-of-stock {
  opacity: 0.45; cursor: not-allowed; pointer-events: none;
}
.tomo-vn-close {
  position: absolute; top: 14px; right: 16px;
  width: 28px; height: 28px; border-radius: 50%;
  border: 2px solid var(--border); background: #fff; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  color: var(--muted); font-size: 14px;
  transition: background 0.14s, color 0.14s;
}
.tomo-vn-close:hover { background: var(--border-soft); color: var(--ink); }

@media (max-width: 600px) {
  .tomo-shop-wrap { padding: 24px 16px 60px; }
  .tomo-page-title { font-size: 1.6rem; }
  .tomo-vn-panel { bottom: 16px; }
}