/* ==========================================================================
   overlay.css — drawers, bottom sheets, backdrop
   --------------------------------------------------------------------------
   HARD CONSTRAINT: nothing that opens may shift the page.

   Every menu, filter panel and mobile table of contents is a fixed overlay
   over a backdrop. None of them are <details> that push content down.

   Three details make that actually true, and all three are easy to miss:

   1. scrollbar-gutter: stable on <html>  (see base.css)
      Without it, locking body scroll removes the scrollbar and the whole
      page jumps sideways.

   2. Scroll lock preserves position  (see shell.js)
      body { position: fixed; top: -<scrollY>px } and restore on close.
      A plain overflow:hidden silently jumps long pages to the top on iOS.

   3. The sticky control bar never grows in place.
      It collapses to a compact button that opens a sheet OVER the page.

   One mechanism, reused by nav / filters / table of contents. Not three.
   ========================================================================== */

/* --------------------------------------------------------------------------
   SCROLL LOCK
   Applied to <body> by shell.js. The inline top offset it also sets is what
   preserves the reading position.
   -------------------------------------------------------------------------- */

body.tcg-scrolllock {
  position: fixed;
  left: 0;
  right: 0;
  width: 100%;
  overflow: hidden;
}

/* --------------------------------------------------------------------------
   BACKDROP
   -------------------------------------------------------------------------- */

.tcg-backdrop {
  position: fixed;
  inset: 0;
  z-index: var(--tcg-z-overlay);
  background: var(--tcg-color-backdrop);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--tcg-dur-med) var(--tcg-ease);
}

.tcg-backdrop.is-open {
  opacity: 1;
  pointer-events: auto;
}

/* --------------------------------------------------------------------------
   OVERLAY PANEL — one component, two presentations.

   Mobile  : bottom sheet, slides up. Thumb-reachable, and the shape people
             expect from Japanese apps.
   >=900px : right-hand drawer, slides in.
   -------------------------------------------------------------------------- */

.tcg-overlay {
  position: fixed;
  z-index: calc(var(--tcg-z-overlay) + 1);
  display: flex;
  flex-direction: column;
  background: var(--tcg-color-surface);
  box-shadow: var(--tcg-shadow-overlay);
  visibility: hidden;

  /* visibility is toggled with a 0s duration, NOT interpolated.
     Transitioning visibility over a duration leaves the element computed as
     hidden for the rest of the current tick, and a visibility:hidden element
     cannot take focus — so focus() silently no-ops and the dialog opens with
     focus stranded on <body>.

     Closed state: delay the flip to hidden until the slide-out has finished,
     so the panel stays visible while it animates away. */
  transition: transform var(--tcg-dur-med) var(--tcg-ease),
              visibility 0s linear var(--tcg-dur-med);
}

/* --- mobile: bottom sheet --- */
.tcg-overlay {
  left: 0;
  right: 0;
  bottom: 0;
  max-height: 85dvh;
  border-radius: var(--tcg-radius-lg) var(--tcg-radius-lg) 0 0;
  transform: translateY(100%);
  /* Home-indicator clearance on iPhone. */
  padding-bottom: env(safe-area-inset-bottom);
}

/* Open state: no delay, so the panel is focusable in the same tick that the
   class is added. */
.tcg-overlay.is-open {
  visibility: visible;
  transform: translateY(0);
  transition: transform var(--tcg-dur-med) var(--tcg-ease),
              visibility 0s linear 0s;
}

/* The panels start below WordPress's admin bar when there is one. Core's
   admin-bar.css defines --wp-admin--admin-bar--height on :root (32px, 46px
   under 783px) only when the bar is rendered, so the fallback is what every
   reader gets and nothing here knows about the bar's breakpoints. */
@media (min-width: 900px) {
  .tcg-overlay {
    left: auto;
    top: var(--wp-admin--admin-bar--height, 0px);
    bottom: 0;
    width: min(420px, 92vw);
    max-height: none;
    border-radius: 0;
    transform: translateX(100%);
    padding-bottom: 0;
  }
  .tcg-overlay.is-open { transform: translateX(0); }

  /* --sheet-modal: a bottom sheet on a phone, a centred dialog from here
     up - the filter sheet (2026-10-15). Unlike --modal below, which is
     centred at every width, this stays attached to the bottom edge where
     its trigger lives on a phone. Five groups of chips need width, not a
     420px drawer, and the body is the only scrolling region, so a long
     product list scrolls inside while the head and the 件を表示 foot stay. */
  .tcg-overlay--sheet-modal {
    left: 50%;
    right: auto;
    top: 50%;
    bottom: auto;
    width: min(760px, 92vw);
    max-height: 85vh;
    border-radius: var(--tcg-radius-lg);
    transform: translate(-50%, -50%) translateY(12px);
  }
  .tcg-overlay--sheet-modal.is-open { transform: translate(-50%, -50%); }
}

/* --- mobile: TOP sheet -------------------------------------------------
   For panels whose trigger lives in the header. A menu opened from a
   top-right hamburger should not require reaching to the bottom of the
   screen to use; the panel comes down from where it was summoned.

   Above 900px this modifier does nothing — the desktop rule below turns
   every overlay into the same right-hand drawer. */
/* Bounded to the narrow range on purpose. This block sits AFTER the 900px
   drawer rule, and both selectors are a single class, so without the bound
   it would beat the drawer at every width and the desktop nav would drop
   from the ceiling. */
@media (max-width: 899px) {
  .tcg-overlay--top {
    top: var(--wp-admin--admin-bar--height, 0px);
    bottom: auto;
    border-radius: 0 0 var(--tcg-radius-lg) var(--tcg-radius-lg);
    transform: translateY(-100%);
    padding-bottom: 0;
    /* Clear the notch / status bar when the panel starts at the very top. */
    padding-top: env(safe-area-inset-top);
  }

  .tcg-overlay--top.is-open { transform: translateY(0); }
}

/* The grab handle is a bottom-sheet affordance. On a top sheet it would sit
   above the title, pointing at nothing. */
.tcg-overlay--top .tcg-overlay__handle { display: none; }

/* --- centred modal -------------------------------------------------------
   Edge panels (drawer, sheet) are for NAVIGATION and CONTROLS: things that
   act on the page behind them, so staying attached to an edge and leaving
   that page visible is right.

   This is for self-contained content you read and dismiss. A 420px drawer
   pinned to the right edge makes prose and tables needlessly narrow and
   drags the reader's eyes to one side for something that is not about the
   right side of anything. Centred at every width, mobile included.

   Placed after the 900px drawer rule deliberately: same specificity, later
   in source, so it wins at all widths — which is the intent here, unlike
   .tcg-overlay--top which had to be bounded. */
.tcg-overlay--modal {
  top: 50%;
  left: 50%;
  right: auto;
  bottom: auto;
  width: min(600px, calc(100vw - 2 * var(--tcg-space-md)));
  max-height: min(82dvh, 720px);
  border-radius: var(--tcg-radius-lg);
  padding-bottom: 0;

  /* Nudged down slightly while closed, so opening reads as a rise rather
     than a pop. translate() carries the centring, so the -50% pair has to
     be repeated in both states. */
  transform: translate(-50%, calc(-50% + 10px));
  opacity: 0;
  transition: transform var(--tcg-dur-med) var(--tcg-ease),
              opacity var(--tcg-dur-med) var(--tcg-ease),
              visibility 0s linear var(--tcg-dur-med);
}

.tcg-overlay--modal.is-open {
  transform: translate(-50%, -50%);
  opacity: 1;
  transition: transform var(--tcg-dur-med) var(--tcg-ease),
              opacity var(--tcg-dur-med) var(--tcg-ease),
              visibility 0s linear 0s;
}

/* A grab handle implies "drag me from this edge". A centred modal has no
   edge to drag from. */
.tcg-overlay--modal .tcg-overlay__handle { display: none; }

@media (prefers-reduced-motion: reduce) {
  .tcg-overlay--modal,
  .tcg-overlay--modal.is-open { transform: translate(-50%, -50%); }
}

/* Grab handle — a bottom-sheet affordance, pointless on the drawer. */
.tcg-overlay__handle {
  flex: none;
  width: 36px;
  height: 4px;
  margin: var(--tcg-space-xs) auto 0;
  border-radius: var(--tcg-radius-pill);
  background: var(--tcg-color-border-strong);
}
@media (min-width: 900px) { .tcg-overlay__handle { display: none; } }

.tcg-overlay__head {
  flex: none;
  display: flex;
  align-items: center;
  gap: var(--tcg-space-xs);
  padding: var(--tcg-space-sm) var(--tcg-space-md);
  border-bottom: 1px solid var(--tcg-color-border);
}

.tcg-overlay__title {
  font-size: var(--tcg-fs-lg);
  font-weight: 700;
}

.tcg-overlay__close {
  margin-left: auto;
  display: inline-grid;
  place-items: center;
  min-width: 44px;
  min-height: 44px;
  border-radius: var(--tcg-radius-sm);
  font-size: var(--tcg-fs-xl);
  color: var(--tcg-color-text-muted);
}
.tcg-overlay__close:hover { background: var(--tcg-color-surface-2); }

/* The only scrolling region while an overlay is open. */
.tcg-overlay__body {
  flex: 1 1 auto;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;   /* no scroll chaining to the locked page */
  padding: var(--tcg-space-md);
}

.tcg-overlay__foot {
  flex: none;
  display: flex;
  gap: var(--tcg-space-xs);
  padding: var(--tcg-space-sm) var(--tcg-space-md);
  border-top: 1px solid var(--tcg-color-border);
  background: var(--tcg-color-surface);
}
.tcg-overlay__foot .tcg-btn { flex: 1; }

/* --------------------------------------------------------------------------
   NAV inside the drawer
   Flat, no submenus. That is partly a UX call — a four-to-six item nav does
   not need them — and partly evidence-gathering: a starter theme's single
   largest JS contribution is submenu keyboard handling, so a flat nav
   removes the strongest reason to take that dependency.
   -------------------------------------------------------------------------- */

.tcg-drawernav { display: flex; flex-direction: column; }

.tcg-drawernav a {
  display: flex;
  align-items: center;
  gap: var(--tcg-space-xs);
  min-height: 52px;
  padding: var(--tcg-space-xs) var(--tcg-space-sm);
  border-bottom: 1px solid var(--tcg-color-border);
  color: var(--tcg-color-text);
  font-weight: 700;
  text-decoration: none;
}
.tcg-drawernav a:hover { background: var(--tcg-color-surface-2); }
.tcg-drawernav a[aria-current="page"] {
  color: var(--tcg-color-brand);
  background: var(--tcg-color-brand-soft);
}

.tcg-drawernav__icon { font-size: var(--tcg-fs-lg); line-height: 1; }

.tcg-drawernav__soon {
  margin-left: auto;
  font-size: var(--tcg-fs-2xs);
  font-weight: 700;
  color: var(--tcg-color-waiting-fg);
  background: var(--tcg-color-waiting-bg);
  border: 1px solid var(--tcg-color-waiting-bd);
  border-radius: var(--tcg-radius-sm);
  padding: 1px var(--tcg-space-2xs);
}

/* --------------------------------------------------------------------------
   Overlays are inert-but-present without JS. Without the script nothing can
   open them, so they must not be reachable by keyboard or screen reader.
   -------------------------------------------------------------------------- */

.no-js .tcg-overlay,
.no-js .tcg-backdrop { display: none; }
