:root {
  /* Color: raw values */
  --raw-color-white: #ffffff;
  --raw-color-surface-gray: #f6f7f9;
  --raw-color-border-gray: #e2e4e8;
  --raw-color-text: #23262b;
  --raw-color-text-muted: #5b6270;
  --raw-color-orange-deep: #c45116;
  --raw-color-orange-deep-hover: #9e3d10;

  /* Color: role names */
  --color-bg: var(--raw-color-white);
  --color-surface: var(--raw-color-surface-gray);
  --color-border: var(--raw-color-border-gray);
  --color-text: var(--raw-color-text);
  --color-text-muted: var(--raw-color-text-muted);
  --color-accent: var(--raw-color-orange-deep);
  --color-accent-hover: var(--raw-color-orange-deep-hover);
  --color-accent-contrast: var(--raw-color-white);
  --color-focus-ring: var(--raw-color-orange-deep-hover);

  /* Typography */
  --font-family-base: -apple-system, BlinkMacSystemFont, "Hiragino Kaku Gothic ProN",
    "Hiragino Sans", "Yu Gothic", Meiryo, sans-serif;
  --font-size-base: 1rem;
  --font-size-xs: 0.75rem;
  --font-size-sm: 0.875rem;
  --font-size-lg: 1.25rem;
  --font-size-xl: 1.5rem;
  --line-height-base: 1.8;
  --line-height-tight: 1.4;

  /* Spacing */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;

  /* Radius */
  --radius-xs: 4px;
  --radius-sm: 6px;
  --radius-md: 8px;
  --radius-lg: 12px;
  --radius-pill: 999px;

  /* Border */
  --border-width: 1px;
  --border-width-thick: 2px;

  /* Shadow */
  --shadow-sm: 0 1px 2px rgba(35, 38, 43, 0.08);
  --shadow-md: 0 2px 8px rgba(35, 38, 43, 0.1);

  /* Layout */
  --content-width: 480px;
  --catalog-width: 1200px;

  /* Catalog / sale colors (kept distinct from --color-accent, which is
     reserved for primary actions). */
  --raw-color-sale-official: #b3261e;
  --raw-color-sale-observed: #6750a4;
  --color-sale-official: var(--raw-color-sale-official);
  --color-sale-observed: var(--raw-color-sale-observed);
  --color-sale-contrast: var(--raw-color-white);

  /* Focus */
  --focus-ring-width: 2px;
  --focus-ring-offset: 2px;

  /* Transition */
  --transition-fast: 150ms ease;
}

* {
  box-sizing: border-box;
}

html {
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  padding: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-family-base);
  font-size: var(--font-size-base);
  line-height: var(--line-height-base);
  min-width: 0;
  overflow-x: hidden;
}

.skip-link {
  position: absolute;
  top: -1000px;
  left: 0;
  z-index: 1000;
  padding: var(--space-2) var(--space-4);
  background: var(--color-accent);
  color: var(--color-accent-contrast);
  border-radius: 0 0 var(--radius-sm) 0;
  text-decoration: none;
  font-weight: 600;
}

.skip-link:focus {
  top: 0;
}

/* ---------------------------------------------------------------------
   Page / layout primitives
   ------------------------------------------------------------------- */

.page {
  max-width: var(--content-width);
  margin: 0 auto;
  padding: var(--space-4);
}

/* The preview-mode top page widens the outer <main> so the catalog preview
   panel can use up to --catalog-width; the standard sections stay centered
   at --content-width via .page-top-standard below. */
.page-top-preview {
  max-width: var(--catalog-width);
}

.page-top-standard {
  max-width: var(--content-width);
  margin: 0 auto;
}

/* Below 900px the main menu is a fixed bar at the bottom of the viewport.
   Everything that has to sit clear of it -- the page tail, the product
   detail CTA bar -- reserves exactly this much space, so the three can
   never be adjusted out of step. */
:root {
  --site-bottom-nav-height: 3.25rem;
}

.site-header {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
  text-align: center;
  margin-bottom: var(--space-4);
}

.site-brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
  color: inherit;
  text-decoration: none;
}

.site-header img {
  width: 132px;
  height: auto;
  max-width: 100%;
}

@media (min-width: 480px) {
  .site-header img {
    width: 180px;
  }
}

.site-name {
  font-size: var(--font-size-xl);
  font-weight: 700;
  margin: 0;
  letter-spacing: 0.04em;
}

.site-reading {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  margin: 0;
}

/* ---------------------------------------------------------------------
   Main menu

   One <nav> serves both layouts: below 900px it is taken out of the
   header's flow and pinned to the bottom of the viewport; from 900px up it
   sits in the header row beside the brand. A single element keeps one tab
   order and one accessible name -- there is no duplicated desktop/mobile
   markup that could drift apart.
   ------------------------------------------------------------------- */

.site-nav-list {
  display: flex;
  list-style: none;
  margin: 0;
  padding: 0;
}

.site-nav-item {
  min-width: 0;
}

.site-nav-link {
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-text);
  text-decoration: none;
  white-space: nowrap;
}

.site-nav-link-current {
  color: var(--color-accent);
  font-weight: 700;
}

@media (hover: hover) and (pointer: fine) {
  .site-nav-link:hover {
    color: var(--color-accent-hover);
  }
}

/* Mobile: fixed bottom bar. Five items share the width evenly, so the
   labels stay legible at 320px (64px per item) without wrapping and
   without the row ever overflowing horizontally. */
@media (max-width: 899px) {
  .site-nav {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 40;
    background: var(--color-bg);
    border-top: var(--border-width) solid var(--color-border);
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }

  .site-nav-list {
    width: 100%;
  }

  .site-nav-item {
    flex: 1 1 0;
  }

  .site-nav-link {
    min-height: var(--site-bottom-nav-height);
    padding: var(--space-1) 2px;
    font-size: var(--font-size-xs);
    line-height: var(--line-height-tight);
    text-align: center;
  }

  .site-nav-link-current {
    box-shadow: inset 0 2px 0 0 var(--color-accent);
  }

  /* Keep the tail of every page clear of the fixed bar. */
  body {
    padding-bottom: calc(var(--site-bottom-nav-height) + env(safe-area-inset-bottom, 0px));
  }
}

/* Desktop: the menu joins the header row, brand left, menu right. */
@media (min-width: 900px) {
  .site-header {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-4);
    text-align: left;
  }

  .site-brand {
    flex-direction: row;
    align-items: baseline;
    gap: var(--space-2);
  }

  .site-nav-list {
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: var(--space-2) var(--space-4);
  }

  .site-nav-link {
    min-height: 44px;
    padding: 0 var(--space-1);
    font-size: var(--font-size-sm);
    border-bottom: var(--border-width-thick) solid transparent;
  }

  .site-nav-link-current {
    border-bottom-color: var(--color-accent);
  }
}

/* ---------------------------------------------------------------------
   Panel / section primitive
   ------------------------------------------------------------------- */

.panel {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  margin-bottom: var(--space-3);
}

.panel > h1,
.panel > h2 {
  margin-top: 0;
}

.gate-notice,
.gate-question {
  margin: 0 0 var(--space-3);
  font-weight: 600;
  line-height: var(--line-height-base);
}

.gate-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* ---------------------------------------------------------------------
   Button primitive
   ------------------------------------------------------------------- */

.btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 44px;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-sm);
  border: var(--border-width-thick) solid transparent;
  font-size: var(--font-size-base);
  font-family: inherit;
  line-height: var(--line-height-tight);
  cursor: pointer;
  text-align: center;
  text-decoration: none;
  transition: background-color var(--transition-fast), border-color var(--transition-fast),
    color var(--transition-fast);
}

.btn-primary {
  background: var(--color-accent);
  color: var(--color-accent-contrast);
  border-color: var(--color-accent);
}

@media (hover: hover) and (pointer: fine) {
  .btn-primary:hover {
    background: var(--color-accent-hover);
    border-color: var(--color-accent-hover);
  }
}

.btn-secondary {
  background: var(--color-bg);
  color: var(--color-accent-hover);
  border-color: var(--color-accent-hover);
}

@media (hover: hover) and (pointer: fine) {
  .btn-secondary:hover {
    background: var(--color-surface);
  }
}

.btn-link {
  background: none;
  border: none;
  color: var(--color-accent);
  text-decoration: underline;
  padding: var(--space-2) 0;
  width: auto;
  min-height: auto;
}

.btn:disabled,
.btn[aria-disabled="true"] {
  cursor: not-allowed;
  opacity: 0.6;
  box-shadow: none;
}

.btn[aria-busy="true"] {
  cursor: progress;
  border-style: dashed;
}

.btn[aria-busy="true"]::after {
  content: "…";
  margin-left: var(--space-1);
}

a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: var(--focus-ring-width) solid var(--color-focus-ring);
  outline-offset: var(--focus-ring-offset);
  box-shadow: 0 0 0 var(--focus-ring-offset) var(--color-bg);
}

/* ---------------------------------------------------------------------
   Badge / status primitive
   ------------------------------------------------------------------- */

.badge,
.status {
  display: inline-block;
  background: var(--color-accent);
  color: var(--color-accent-contrast);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  font-size: var(--font-size-sm);
  font-weight: 600;
  margin: 0;
}

/* ---------------------------------------------------------------------
   Text primitives
   ------------------------------------------------------------------- */

.text-muted {
  color: var(--color-text-muted);
}

.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;
}

.hero h1 {
  font-size: var(--font-size-lg);
  line-height: var(--line-height-tight);
  margin: 0 0 var(--space-2);
}

.planned-features h2,
.current-status h2 {
  font-size: var(--font-size-base);
  font-weight: 700;
  margin: 0 0 var(--space-2);
}

.planned-features ul {
  margin: 0;
  padding-left: 20px;
}

.planned-features li {
  margin-bottom: var(--space-1);
}

.ad-notice p {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  margin: 0;
}

/* ---------------------------------------------------------------------
   Footer
   ------------------------------------------------------------------- */

.site-footer {
  margin-top: var(--space-4);
  text-align: center;
}

.site-footer nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}

.site-footer a {
  color: var(--color-accent);
}

/* ---------------------------------------------------------------------
   404 page
   ------------------------------------------------------------------- */

.page-not-found h1 {
  font-size: var(--font-size-lg);
  margin: 0 0 var(--space-2);
}

/* ---------------------------------------------------------------------
   Catalog preview notice
   ------------------------------------------------------------------- */

.catalog-preview-section {
  overflow: visible;
}

.catalog-preview-notice {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  margin: 0 0 var(--space-3);
}

/* ---------------------------------------------------------------------
   Catalog grid / product card
   ------------------------------------------------------------------- */

.catalog-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
  list-style: none;
  margin: 0 auto;
  padding: 0;
  max-width: 900px;
}

@media (min-width: 360px) {
  .catalog-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 600px) {
  .catalog-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (min-width: 900px) {
  .catalog-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    max-width: var(--catalog-width);
  }
}

.catalog-grid-item {
  min-width: 0;
}

/* EC-style card: the media fills the card's full width edge-to-edge (the
   card itself has no padding; only the text body below is inset), the
   corners are only mildly rounded, and vertical spacing is compressed so
   image -> title -> price dominate. */
.product-card {
  position: relative;
  display: flex;
  flex-direction: column;
  min-width: 0;
  /* Fill the grid cell so every card in a row shares the row height and the
     bottoms line up regardless of title/price line counts. */
  height: 100%;
  background: var(--color-bg);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-sm);
  overflow: hidden;
  padding: 0;
}

.product-card-media {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 3;
  background: var(--color-surface);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* DUGA material rules: never crop or alter the image itself. contain keeps
   the full image visible at its own aspect ratio -- posters (240x180, 4:3)
   fill the 4:3 box exactly, jackets (~3:2) sit on the surface background
   with thin bars. */
.product-card-image {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.product-card-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-surface);
  color: var(--color-text-muted);
}

.product-card-placeholder-mark {
  font-size: var(--font-size-xl);
  font-weight: 700;
}

.favorite-button-wrap {
  width: 100%;
  min-width: 0;
}

.favorite-button {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin-left: auto;
  padding: 0;
  border-radius: var(--radius-pill);
  border: var(--border-width-thick) solid var(--color-border);
  background: var(--color-bg);
  cursor: pointer;
}

.favorite-button[aria-pressed="true"] {
  border-color: var(--color-accent);
}

.favorite-button[aria-busy="true"] {
  cursor: progress;
  opacity: 0.7;
}

/* Heart rendered as a text glyph (♡/♥) so no CSP relaxation is needed for
   data: image masks. */
.favorite-button-icon {
  display: inline-block;
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 20px;
  line-height: 1;
  color: var(--color-accent);
}

.favorite-error {
  width: 100%;
  margin: var(--space-1) 0 0;
  font-size: var(--font-size-sm);
  color: var(--color-sale-official);
  text-align: left;
}

/* ---------------------------------------------------------------------
   Favorites: shared announcer toast + corrupt/unavailable storage notice
   ------------------------------------------------------------------- */

.favorites-toast {
  margin: 0;
  font-size: var(--font-size-sm);
}

.favorites-toast:not(:empty) {
  padding: var(--space-2) var(--space-4);
  margin-bottom: var(--space-3);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
}

.favorites-page-notice p {
  margin: 0 0 var(--space-2);
  font-weight: 600;
}

.favorites-reset-button {
  width: auto;
}

.favorites-reset-failed {
  margin: 0 0 var(--space-2);
  color: var(--color-sale-official);
}

.favorites-recovery-warning {
  margin: 0 0 var(--space-3);
  padding: var(--space-2) var(--space-4);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  font-size: var(--font-size-sm);
}

.product-card-primary-link {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
  color: var(--color-text);
  text-decoration: none;
  font-weight: 600;
}

.product-card-primary-link:hover .product-card-title {
  text-decoration: underline;
}

/* Exactly 2 lines of title height: clamp long titles with an ellipsis and
   reserve the same 2-line box under 1-line titles, so the blocks below sit
   at the same offset on every card in a row. */
.product-card-title {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  padding: var(--space-1) var(--space-2) 0;
  font-size: var(--font-size-sm);
  line-height: var(--line-height-tight);
  min-height: calc(2 * var(--line-height-tight) * 1em);
}

/* Everything below the title: price first, then de-emphasized metadata.
   margin-top:auto keeps price blocks bottom-aligned across a grid row when
   titles wrap to different line counts. */
.product-card-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
  margin-top: auto;
  padding: var(--space-1) var(--space-2) var(--space-2);
}

.product-card-reason {
  margin: 0;
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Auxiliary metadata never exceeds one line. */
.product-card-category,
.product-card-date {
  margin: 0;
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---------------------------------------------------------------------
   Sale badge
   ------------------------------------------------------------------- */

.sale-badge {
  display: inline-block;
  align-self: flex-start;
  padding: 2px var(--space-2);
  border-radius: var(--radius-xs);
  font-size: var(--font-size-xs);
  font-weight: 600;
  color: var(--color-sale-contrast);
}

.sale-badge-official {
  background: var(--color-sale-official);
}

.sale-badge-observed {
  background: var(--color-sale-observed);
}

/* ---------------------------------------------------------------------
   Price row
   ------------------------------------------------------------------- */

.price-row {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  list-style: none;
  margin: 0;
  padding: 0;
  min-width: 0;
  /* Reserve the height of a price line + plan-label line so cards with and
     without a discount cluster keep near-identical price-block heights. */
  min-height: calc(var(--font-size-lg) * var(--line-height-tight) + var(--font-size-xs) * 1.5 + 2px);
}

/* One plan's price cluster: current price (strongest), struck reference
   price and discount chip immediately beside it, plan label as a small
   muted suffix. Kept on one wrapping line so the pieces never separate. */
.price-row-item {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: var(--space-2);
  row-gap: 2px;
  min-width: 0;
  margin: 0;
}

.price-line {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: var(--space-2);
  row-gap: 2px;
  min-width: 0;
}

.price-current {
  font-size: var(--font-size-lg);
  font-weight: 700;
  line-height: var(--line-height-tight);
  overflow-wrap: break-word;
}

.price-reference {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  text-decoration: line-through;
}

.price-discount {
  font-size: var(--font-size-xs);
  font-weight: 700;
  line-height: 1.5;
  padding: 0 var(--space-1);
  border-radius: var(--radius-xs);
  background: var(--color-sale-official);
  color: var(--color-sale-contrast);
  white-space: nowrap;
}

.price-row-label {
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
  overflow-wrap: break-word;
}

.price-row-unknown {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  overflow-wrap: break-word;
}

.catalog-preview-states {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  margin-top: var(--space-5);
}

.catalog-preview-state-example h3 {
  font-size: var(--font-size-base);
  margin: 0 0 var(--space-2);
}

/* ---------------------------------------------------------------------
   Catalog state (loading / empty / error)
   ------------------------------------------------------------------- */

.catalog-state {
  padding: var(--space-5) var(--space-4);
  text-align: center;
}

.catalog-skeleton-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: var(--space-4);
  list-style: none;
  margin: 0;
  padding: 0;
}

.catalog-skeleton-card {
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-sm);
  background: linear-gradient(
    90deg,
    var(--color-surface) 25%,
    var(--color-border) 37%,
    var(--color-surface) 63%
  );
  background-size: 400% 100%;
  animation: catalog-skeleton-shimmer 1.4s ease infinite;
}

@keyframes catalog-skeleton-shimmer {
  0% {
    background-position: 100% 50%;
  }
  100% {
    background-position: 0 50%;
  }
}

/* ---------------------------------------------------------------------
   Motion
   ------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  * {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---------------------------------------------------------------------
   Search page
   ------------------------------------------------------------------- */

.page-search {
  max-width: var(--catalog-width);
}

.page-search h1 {
  font-size: var(--font-size-lg);
  margin: 0 0 var(--space-3);
}

.search-preview-notice {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

.search-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

/* One shared vertical rhythm for keyword row -> toolbar -> chips -> grid,
   instead of each block bringing its own margins. (sales-form shares this
   class and inherits the same rhythm.) */
.search-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.search-keyword-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.search-keyword-label {
  font-weight: 600;
}

/* Below 480px the inline label would squeeze the input into a sliver and
   push the button onto a lonely row; a stacked label keeps input + button
   together on one usable line. */
@media (max-width: 479px) {
  .search-keyword-label {
    flex-basis: 100%;
  }
}

.search-keyword-input {
  flex: 1 1 240px;
  min-width: 0;
  padding: var(--space-2) var(--space-3);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-sm);
  font-size: var(--font-size-base);
  font-family: inherit;
}

.search-submit-btn {
  width: auto;
  flex: 0 0 auto;
}

.search-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.search-total-count {
  margin: 0;
  font-weight: 600;
}

.search-sort-label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-sm);
}

.search-sort-select {
  padding: var(--space-1) var(--space-2);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-sm);
  font-family: inherit;
  font-size: var(--font-size-base);
}

.search-layout {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  min-width: 0;
}

.search-sidebar {
  display: none;
}

.search-filter-fieldset {
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-3);
  min-width: 0;
}

.search-filter-fieldset legend {
  font-weight: 600;
  padding: 0 var(--space-1);
}

/* Desktop sidebar: one quiet panel with divider-separated sections, not
   five floating boxes -- the results stay the page's main subject. The
   filter drawer keeps its own boxed fieldsets (these overrides are scoped
   to the sidebar only). */
.search-sidebar .search-filter-fieldset {
  border: none;
  border-radius: 0;
  padding: var(--space-3) var(--space-3) var(--space-2);
  margin: 0;
}

.search-sidebar .search-filter-fieldset + .search-filter-fieldset {
  border-top: var(--border-width) solid var(--color-border);
}

.search-sidebar .search-filter-fieldset legend {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  padding: 0;
  /* A legend floats into the fieldset's (now removed) border gap; pushing
     it back into flow keeps the label aligned with its controls. */
  margin-bottom: var(--space-1);
}

.search-sidebar .search-checkbox-label {
  margin-bottom: var(--space-1);
}

.search-sidebar-apply {
  width: auto;
  margin: var(--space-2) var(--space-3) var(--space-3);
}

.search-checkbox-label,
.search-number-label,
.search-date-label {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-2);
  font-size: var(--font-size-sm);
  min-width: 0;
}

.search-number-label,
.search-date-label {
  flex-direction: column;
  align-items: flex-start;
}

.search-number-label input,
.search-date-label input {
  width: 100%;
  padding: var(--space-1) var(--space-2);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-sm);
  font-family: inherit;
}

.search-results-area {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
}

.search-chip-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  list-style: none;
  margin: 0;
  padding: 0;
}

.search-chip {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  padding: var(--space-1) var(--space-2);
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-sm);
  font-size: var(--font-size-sm);
}

.search-chip-remove {
  color: var(--color-accent);
  text-decoration: none;
  font-weight: 700;
}

.search-confirmed-at {
  margin: 0;
  font-size: var(--font-size-sm);
}

.search-results-grid {
  max-width: none;
}

.search-pagination {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-3);
}

.search-pagination .btn {
  width: auto;
}

.search-filter-drawer-trigger {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: var(--space-2) var(--space-3);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-pill);
  background: var(--color-surface);
  color: var(--color-text);
  font-family: inherit;
  font-size: var(--font-size-sm);
  font-weight: 600;
  cursor: pointer;
}

.search-filter-drawer {
  border: none;
  border-radius: 0;
  padding: 0;
  margin: 0;
  width: 100%;
  max-width: 100%;
  height: 100%;
  max-height: 100%;
  min-width: 0;
  background: var(--color-bg);
  color: var(--color-text);
}

.search-filter-drawer::backdrop {
  background: rgba(35, 38, 43, 0.5);
}

.search-filter-drawer[open] {
  display: flex;
  flex-direction: column;
}

.search-filter-drawer-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-4);
  border-bottom: var(--border-width) solid var(--color-border);
}

.search-filter-drawer-header h2 {
  margin: 0;
  font-size: var(--font-size-lg);
}

.search-filter-drawer-close {
  min-width: 44px;
  min-height: 44px;
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-bg);
  font-size: var(--font-size-lg);
  line-height: 1;
  cursor: pointer;
}

.search-filter-drawer-form {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
}

.search-filter-drawer-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.search-filter-drawer .search-checkbox-label {
  min-height: 44px;
  padding: var(--space-2) 0;
}

.search-filter-drawer .search-checkbox-label input[type="checkbox"] {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
}

.search-filter-drawer .search-number-label input,
.search-filter-drawer .search-date-label input {
  box-sizing: border-box;
  min-height: 44px;
  max-width: 100%;
}

.search-filter-drawer-count {
  margin: 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

.search-filter-drawer-entity-list {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  list-style: none;
  margin: 0;
  padding: 0;
}

.search-filter-drawer-entity-list .search-chip-remove {
  background: none;
  border: none;
  padding: 0;
  font-family: inherit;
  font-size: inherit;
  cursor: pointer;
  min-width: 44px;
  min-height: 44px;
}

.search-filter-drawer-footer {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding: var(--space-4);
  padding-bottom: calc(var(--space-4) + env(safe-area-inset-bottom, 0px));
  border-top: var(--border-width) solid var(--color-border);
  position: sticky;
  bottom: 0;
  background: var(--color-bg);
}

.search-filter-drawer-footer .btn {
  flex: 1 1 auto;
  min-height: 44px;
  width: auto;
}

@media (max-height: 640px) {
  .search-filter-drawer[open] {
    display: block;
    overflow-y: auto;
  }

  .search-filter-drawer-form {
    display: block;
  }

  .search-filter-drawer-body {
    flex: none;
    overflow-y: visible;
  }

  .search-filter-drawer-footer {
    position: static;
  }
}

@media (min-width: 900px) {
  .search-filter-drawer-trigger,
  .search-filter-drawer {
    display: none;
  }

  .search-filter-drawer[open] {
    display: none;
  }

  .search-layout {
    flex-direction: row;
    align-items: flex-start;
  }

  .search-sidebar {
    display: flex;
    flex-direction: column;
    gap: 0;
    min-width: 0;
    flex: 0 0 280px;
    width: 280px;
    /* The one container the divider-separated sections live in. */
    border: var(--border-width) solid var(--color-border);
    border-radius: var(--radius-sm);
    background: var(--color-bg);
    align-self: flex-start;
  }

  .search-results-area {
    flex: 1 1 auto;
  }
}

/* ---------------------------------------------------------------------
   Product detail page
   ------------------------------------------------------------------- */

.page-product-detail {
  max-width: var(--catalog-width);
}

.product-breadcrumb ol {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  list-style: none;
  margin: 0 0 var(--space-3);
  padding: 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

.product-breadcrumb li:not(:last-child)::after {
  content: "›";
  margin-left: var(--space-1);
}

.product-breadcrumb a {
  color: var(--color-text-muted);
}

.product-detail-preview-notice {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

.product-detail-top {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  min-width: 0;
}

.product-detail-top-media,
.product-detail-top-info {
  min-width: 0;
}

.product-detail-media {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 3;
  background: var(--color-surface);
  border-radius: var(--radius-md);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

.product-detail-image {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.product-detail-image-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-surface);
  color: var(--color-text-muted);
  font-size: var(--font-size-xl);
  font-weight: 700;
}

/* The work's name heads the whole product block, media and prices alike. */
.product-detail-heading {
  margin: 0 0 var(--space-3);
}

.product-detail-heading h1 {
  font-size: var(--font-size-lg);
  line-height: var(--line-height-tight);
  margin: 0;
  overflow-wrap: anywhere;
}

.product-detail-original-title {
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
  margin: var(--space-1) 0 0;
}

.product-detail-price-block {
  margin-bottom: var(--space-3);
}

.product-detail-price-unavailable {
  font-weight: 600;
}

/* One box, one divider per plan -- not a stack of four separate cards.
   Prices right-align in a shared column (tabular digits) so 四 plans scan
   as one price list; the struck comparison price sits directly beside the
   current price, exactly like the listing cards. */
.product-detail-offer-list {
  list-style: none;
  margin: 0 0 var(--space-2);
  padding: 0;
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-sm);
}

.product-detail-offer-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-1) var(--space-3);
  padding: var(--space-2) var(--space-3);
}

.product-detail-offer-row + .product-detail-offer-row {
  border-top: var(--border-width) solid var(--color-border);
}

.product-detail-offer-plan {
  font-size: var(--font-size-sm);
  font-weight: 600;
}

.product-detail-offer-price-cluster {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: flex-end;
  column-gap: var(--space-2);
  min-width: 0;
  margin-left: auto;
}

.product-detail-offer-price {
  font-size: var(--font-size-lg);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: var(--line-height-tight);
}

.product-detail-offer-reference {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  text-decoration: line-through;
}

.product-detail-confirmed-at {
  margin: 0 0 var(--space-3);
  font-size: var(--font-size-xs);
}

/* ---------------------------------------------------------------------
   New releases (newest-first listing)
   ------------------------------------------------------------------- */

.page-new-releases {
  max-width: var(--catalog-width);
}

.new-releases-intro {
  margin: 0 0 var(--space-3);
  font-size: var(--font-size-sm);
}

/* The grid sits directly on the page rather than beside a sidebar, so the
   shared catalog grid's centring max-width is exactly what is wanted here
   and is deliberately left in place. */
.new-releases-pagination {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-4);
}

.new-releases-first,
.new-releases-next {
  flex: 1 1 auto;
  min-width: 0;
}

@media (min-width: 600px) {
  .new-releases-first,
  .new-releases-next {
    flex: 0 0 auto;
    min-width: 160px;
  }
}

/* ---------------------------------------------------------------------
   Top page (brand entrance: hero, ways of finding, new-releases taste)
   ------------------------------------------------------------------- */

.page-home {
  max-width: var(--catalog-width);
}

.home-hero {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-5) var(--space-4) var(--space-6);
  text-align: center;
}

.home-hero-copy {
  margin: 0;
  font-size: 1.75rem;
  line-height: var(--line-height-tight);
  letter-spacing: 0.02em;
  text-wrap: balance;
}

.home-hero-lead {
  margin: 0;
  max-width: 34em;
  font-size: var(--font-size-sm);
  text-wrap: balance;
}

.home-hero-actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-3);
  margin-top: var(--space-2);
  width: 100%;
  max-width: 560px;
}

.home-hero-cta {
  flex: 1 1 220px;
  width: auto;
}

@media (max-width: 479px) {
  .home-hero {
    padding: var(--space-4) var(--space-2) var(--space-5);
  }

  .home-hero-copy {
    font-size: var(--font-size-xl);
  }
}

.home-section-heading {
  margin: 0 0 var(--space-3);
  font-size: var(--font-size-lg);
}

/* Ways of finding: one bordered list, each row a single link. Density over
   card pomp -- the title leads, the one-liner stays muted, the arrow is
   the only ornament. */
.home-methods {
  margin: var(--space-4) 0;
}

.home-method-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-bg);
}

.home-method-item + .home-method-item {
  border-top: var(--border-width) solid var(--color-border);
}

.home-method-link {
  display: grid;
  grid-template-columns: minmax(0, auto) minmax(0, 1fr) auto;
  align-items: baseline;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  color: inherit;
  text-decoration: none;
  min-height: 44px;
}

.home-method-title {
  font-weight: 600;
  white-space: nowrap;
}

.home-method-description {
  font-size: var(--font-size-sm);
  overflow-wrap: anywhere;
}

.home-method-arrow {
  color: var(--color-accent);
  font-weight: 600;
}

@media (hover: hover) and (pointer: fine) {
  .home-method-link:hover {
    background: var(--color-surface);
  }

  .home-method-link:hover .home-method-title {
    color: var(--color-accent-hover);
  }
}

/* Below 480px the one-liner drops under the title so neither is squeezed. */
@media (max-width: 479px) {
  .home-method-link {
    grid-template-columns: minmax(0, 1fr) auto;
  }

  .home-method-description {
    grid-column: 1 / -1;
  }
}

.home-new-releases {
  margin: var(--space-5) 0;
}

.home-more-link {
  width: auto;
  min-width: 220px;
  margin: var(--space-4) auto 0;
}

/* The discover feature band: brand UI only, one accent border to lift it a
   step above the method list -- no image, no video, no gradient. */
.home-discover-feature {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  margin: var(--space-5) 0;
  padding: var(--space-5) var(--space-4);
  border: var(--border-width) solid var(--color-border);
  border-left: 3px solid var(--color-accent);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  text-align: center;
}

.home-discover-feature .home-section-heading {
  margin-bottom: 0;
}

.home-discover-lead {
  margin: 0;
  max-width: 34em;
  font-size: var(--font-size-sm);
}

.home-discover-cta {
  width: auto;
  min-width: 220px;
  margin-top: var(--space-2);
}

/* ---------------------------------------------------------------------
   Discover (one product at a time, sample-video led)
   ------------------------------------------------------------------- */

.page-discover {
  max-width: 980px;
}

.discover-intro {
  margin: 0 0 var(--space-3);
  font-size: var(--font-size-sm);
}

/* Every 次の作品 lands back at the top of the document, so on a phone the
   heading block above the card decides whether the new preview is already
   in view. Tightened (not hidden -- the disclosure keeps its full wording)
   so the surface starts inside the first viewport. */
@media (max-width: 599px) {
  .page-discover h1 {
    margin-bottom: var(--space-2);
    font-size: var(--font-size-lg);
  }

  .page-discover .discover-intro {
    margin-bottom: var(--space-2);
  }

  .page-discover .affiliate-disclosure-notice {
    margin-bottom: var(--space-2);
    font-size: var(--font-size-xs);
  }
}

.discover-card {
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--color-bg);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

/* Media pane beside the info column once there is room: the preview
   surface stays the largest element on screen, and title/price/actions sit
   in the same eye span instead of below the fold. */
@media (min-width: 900px) {
  .discover-card {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 300px;
    align-items: stretch;
  }
}

/* The preview surface: one full-size button. The capture (or fallback
   image) is shown whole -- contain, never cover, no cropping or transform
   of DUGA material (docs/78) -- and the play affordance is a separate
   block placed below the material, never a dimming/color layer or an
   icon/label baked on top of it. */
.discover-preview {
  display: flex;
  flex-direction: column;
  width: 100%;
  padding: 0;
  border: none;
  background: var(--color-surface);
  overflow: hidden;
  cursor: pointer;
}

.discover-preview-media {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  aspect-ratio: 4 / 3;
  background: var(--color-surface);
  overflow: hidden;
}

.discover-preview-image {
  width: 100%;
  height: 100%;
  object-fit: contain;
}

.discover-preview-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-surface);
  color: var(--color-text-muted);
}

.discover-placeholder-mark {
  font-size: var(--font-size-xl);
  font-weight: 700;
}

.discover-preview-control {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-top: var(--border-width) solid var(--color-border);
  background: var(--color-surface);
  transition: background-color 120ms ease;
}

.discover-preview-play-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  border-radius: 50%;
  background: var(--color-accent);
  color: var(--color-accent-contrast);
  transition: transform 120ms ease;
}

.discover-preview-play-icon svg {
  margin-left: 2px;
}

.discover-preview-play-label {
  color: var(--color-text);
  font-size: var(--font-size-sm);
  font-weight: 600;
}

.discover-preview:hover .discover-preview-control,
.discover-preview:focus-visible .discover-preview-control {
  background: var(--color-bg);
}

.discover-preview:hover .discover-preview-play-icon,
.discover-preview:focus-visible .discover-preview-play-icon {
  transform: scale(1.06);
}

.discover-preview:focus-visible {
  outline: 3px solid var(--color-accent);
  outline-offset: -3px;
}

@media (prefers-reduced-motion: reduce) {
  .discover-preview-play-icon {
    transition: none;
  }
}

.discover-body {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-2);
  min-width: 0;
  padding: var(--space-3);
}

@media (min-width: 900px) {
  .discover-body {
    border-left: var(--border-width) solid var(--color-border);
  }
}

.discover-title {
  margin: 0;
  font-size: var(--font-size-lg);
  line-height: var(--line-height-tight);
  overflow-wrap: anywhere;
}

.discover-meta {
  margin: 0;
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
  overflow-wrap: anywhere;
}

/* Detail first, next right under it: conversion keeps the stronger style,
   momentum keeps the same size and reach. margin-top:auto pins the pair to
   the bottom of the side column on desktop. */
.discover-actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  width: 100%;
  margin-top: auto;
}

.discover-detail-link {
  width: 100%;
}

.discover-nav {
  display: flex;
  width: 100%;
}

.discover-next {
  flex: 1 1 auto;
}

/* --- Sample modal ---------------------------------------------------- */

/* A dialog in the top layer sizes against the viewport, so percentages do
   what vw units would -- without the classic viewport-width scrollbar overflow this
   stylesheet bans. */
.discover-modal {
  width: min(920px, calc(100% - 2 * var(--space-4)));
  max-height: calc(100vh - 3rem);
  padding: 0;
  border: none;
  border-radius: var(--radius-sm);
  background: var(--color-bg);
  color: var(--color-text);
}

.discover-modal::backdrop {
  background: rgba(17, 17, 17, 0.6);
}

.discover-modal-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-2) var(--space-2) var(--space-3);
  border-bottom: var(--border-width) solid var(--color-border);
}

.discover-modal-title {
  margin: 0;
  font-size: var(--font-size-sm);
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.discover-modal-close {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 2.75rem;
  height: 2.75rem;
  padding: 0;
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text);
  cursor: pointer;
}

.discover-modal-close:hover,
.discover-modal-close:focus-visible {
  background: var(--color-surface);
}

.discover-modal-video {
  display: block;
  width: 100%;
  max-height: 70vh;
  background: #000;
}

.discover-modal-status {
  margin: 0;
  padding: var(--space-4) var(--space-3);
  text-align: center;
  color: var(--color-text-muted);
}

.discover-modal-actions {
  display: flex;
  justify-content: flex-end;
  padding: var(--space-2) var(--space-3) var(--space-3);
}

@media (max-width: 599px) {
  .discover-modal {
    width: calc(100% - var(--space-3));
  }

  .discover-modal-actions {
    justify-content: stretch;
  }

  .discover-modal-detail-link {
    width: 100%;
  }
}

/* ---------------------------------------------------------------------
   Sample movie (product detail and discover)
   ------------------------------------------------------------------- */

.sample-movie {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  align-items: flex-start;
}

.sample-movie-button {
  width: auto;
}

/* Playback opens inside this native dialog; it is server-rendered closed,
   with the video inside carrying no src and no poster until the visitor's
   request resolves. */
.sample-movie-dialog {
  width: min(90vw, 720px);
  max-width: 90vw;
  max-height: 90vh;
  padding: var(--space-3);
  border: none;
  border-radius: var(--radius-sm);
  background: var(--color-surface);
}

.sample-movie-dialog::backdrop {
  background: rgba(0, 0, 0, 0.6);
}

.sample-movie-dialog-panel {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  align-items: flex-end;
}

.sample-movie-video {
  width: 100%;
  max-width: 100%;
  background: var(--color-surface);
  border-radius: var(--radius-sm);
}

.sample-movie-error {
  margin: 0;
  font-size: var(--font-size-sm);
  color: var(--color-sale-official);
}

.product-detail-below {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  min-width: 0;
}

.product-detail-caption p {
  white-space: pre-line;
  margin: 0;
}

/* The caption and the attribute table are reading material, so they keep a
   readable measure instead of stretching hairline rules across the full
   1200px catalog width. The related grid below them stays full width. */
.product-detail-caption,
.product-detail-attributes,
.product-detail-entity-group {
  max-width: 860px;
}

.product-detail-attributes {
  margin: 0;
}

.product-detail-attribute-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  padding: var(--space-1) 0;
  border-bottom: var(--border-width) solid var(--color-border);
  font-size: var(--font-size-sm);
}

.product-detail-attribute-row dt {
  min-width: 8em;
  color: var(--color-text-muted);
  font-weight: 600;
}

.product-detail-attribute-row dd {
  margin: 0;
}

/* Heading and chips share one row: four near-empty sections were eating
   a full screen of vertical space for one chip each. */
.product-detail-entity-group {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-1) var(--space-3);
}

.product-detail-entity-group h3 {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  margin: 0;
  min-width: 5em;
}

.product-detail-entity-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.product-detail-entity-list li {
  background: var(--color-surface);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-pill);
  padding: var(--space-1) var(--space-3);
  font-size: var(--font-size-sm);
}

.product-detail-related h2 {
  font-size: var(--font-size-lg);
  margin: 0 0 var(--space-3);
}

.product-detail-related-notice {
  color: var(--color-text-muted);
}

.product-detail-related-grid {
  max-width: none;
}

@media (min-width: 900px) {
  .product-detail-top {
    display: grid;
    grid-template-columns: minmax(320px, 5fr) minmax(420px, 7fr);
    gap: var(--space-5);
    align-items: start;
  }
}

/* ---------------------------------------------------------------------
   DUGA affiliate CTA / disclosure notice / credit footer
   ------------------------------------------------------------------- */

/* docs/103 §2: at least 14px (--font-size-sm is exactly that), readable
   against the page background, never collapsed or hidden behind a hover. */
.affiliate-disclosure-notice {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  margin: 0 0 var(--space-3);
}

.affiliate-disclosure-link {
  margin-left: var(--space-2);
  color: var(--color-accent-hover);
  white-space: nowrap;
}

/* ---------------------------------------------------------------------
   /advertising (広告について)
   ------------------------------------------------------------------- */

.advertising-body p {
  margin: 0 0 var(--space-3);
}

.advertising-body p:last-child {
  margin-bottom: 0;
}

/* One action row, not four stacked fragments: 広告 label, favorite and the
   DUGA link sit on a single line (DOM order preserved), with the note as a
   full-width second line. */
.affiliate-cta-block {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  margin-top: var(--space-3);
}

.affiliate-cta-ad-label {
  display: inline-block;
  font-size: var(--font-size-sm);
  font-weight: 700;
  line-height: 1;
  padding: var(--space-1) var(--space-2);
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
}

/* The current product's favorite control shares this block with the CTA
   link so the two never render in two separate places -- on narrow
   viewports the whole block (including this favorite control) becomes the
   single fixed bottom bar, never a duplicated second favorite button. */
.affiliate-cta-favorite .favorite-button-wrap {
  width: auto;
}

.affiliate-cta-favorite .favorite-button {
  margin-left: 0;
}

/* The page's one conversion action wears the brand accent -- the same
   #C45116 every primary button uses -- instead of the near-black box it
   was, and drops the default link underline that made it read as body text
   pasted onto a banner. */
.affiliate-cta-link {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--space-1) var(--space-2);
  min-height: 44px;
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-sm);
  background: var(--color-accent);
  color: var(--color-accent-contrast);
  font-weight: 700;
  text-align: center;
  text-decoration: none;
  flex: 1 1 auto;
}

@media (hover: hover) and (pointer: fine) {
  .affiliate-cta-link:hover {
    background: var(--color-accent-hover);
  }
}

.affiliate-cta-link-hint {
  font-size: var(--font-size-xs);
  font-weight: 400;
  opacity: 0.9;
  white-space: nowrap;
}

.affiliate-cta-note {
  margin: 0;
  font-size: var(--font-size-xs);
  color: var(--color-text-muted);
  flex-basis: 100%;
}

.affiliate-cta-unavailable {
  margin: 0;
  font-weight: 600;
}

.affiliate-credit-footer {
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: var(--border-width) solid var(--color-border);
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

/* Below 900px, the single CTA block already rendered in the normal flow is
   repositioned as a fixed bottom bar -- never duplicated as a second link --
   only while a real, gate-passing href is present
   (.affiliate-cta-block--available, toggled by the route from the exact
   same affiliateCtaHref value used for the href itself). When the CTA is
   unavailable, .has-affiliate-cta is never added to <main> and this block
   stays a plain, static, in-flow stop message with no reserved fixed
   space. The reserved bottom padding on <main> and the fixed bar's own
   max-height always share the same `--affiliate-cta-fixed-space` value --
   in rem units so both grow together under 200% text-only zoom -- so the
   bar can never grow taller than the space reserved for it and cover the
   footer/body tail; if wrapped content (long note text, larger zoom, a
   narrow viewport) would exceed that shared height, the bar scrolls
   internally instead of expanding past it. */
@media (max-width: 899px) {
  .has-affiliate-cta {
    --affiliate-cta-fixed-space: 8rem;
    /* The main menu already reserves its own height on <body>; this adds
       only the CTA bar's share on top, so the two stack instead of one
       covering the other. */
    padding-bottom: calc(var(--affiliate-cta-fixed-space) + env(safe-area-inset-bottom, 0px));
  }

  /* The CTA bar sits directly above the fixed main menu (z-index 40), never
     over it, so the menu stays reachable while a CTA is on screen. */
  .has-affiliate-cta .affiliate-cta-block--available {
    position: fixed;
    left: 0;
    right: 0;
    bottom: calc(var(--site-bottom-nav-height) + env(safe-area-inset-bottom, 0px));
    z-index: 30;
    flex-direction: row;
    align-items: center;
    flex-wrap: wrap;
    margin: 0;
    /* The safe-area inset is absorbed by the main menu below this bar, so
       neither the height nor the padding adds it a second time. */
    max-height: var(--affiliate-cta-fixed-space);
    overflow-y: auto;
    background: var(--color-bg);
    border-top: var(--border-width) solid var(--color-border);
    padding: var(--space-2) var(--space-4);
    gap: var(--space-2) var(--space-3);
  }

  /* Inside the fixed bar the four pieces settle into two short rows --
     favorite + link, then 広告 label + note -- so the whole bar fits its
     reserved height even at 320px and the note is never clipped
     mid-sentence. Visual order only (CSS `order`); the DOM and tab order
     stay label, favorite, link, note. */
  .has-affiliate-cta .affiliate-cta-block--available .affiliate-cta-ad-label {
    order: 2;
  }

  .has-affiliate-cta .affiliate-cta-block--available .affiliate-cta-note {
    order: 3;
    /* Zero flex base so the note shares its row with the 広告 label instead
       of wrapping onto a third row at its full sentence width. */
    flex: 1 1 0;
    min-width: 0;
  }
}

/* A short viewport (e.g. landscape phone, or 200% text zoom shrinking the
   effective viewport) drops the fixed bar back into normal flow so it can
   never cover the page footer or the tail of the body content. */
@media (max-width: 899px) and (max-height: 480px) {
  .has-affiliate-cta {
    padding-bottom: var(--space-4);
  }

  .has-affiliate-cta .affiliate-cta-block--available {
    position: static;
  }
}

/* ---------------------------------------------------------------------
   /favorites page
   ------------------------------------------------------------------- */

/* The saved list is a catalog grid like every other listing, so it needs the
   catalog width rather than the narrow default --content-width; without this
   the grid still steps to four columns at >=900px but inside a 480px page,
   squeezing each card to about 110px. The grid's own responsive steps are
   untouched, so 320px still renders a single column. */
.page-favorites {
  max-width: var(--catalog-width);
}

.page-favorites h1 {
  margin: 0 0 var(--space-3);
}

.favorites-count-block {
  margin: 0 0 var(--space-4);
}

.favorites-count-line {
  margin: 0;
  font-weight: 600;
}

.favorites-sync-notice {
  margin: var(--space-1) 0 0;
  font-size: var(--font-size-sm);
}

.favorites-empty {
  text-align: center;
}

.favorites-empty h2 {
  margin: 0 0 var(--space-2);
}

.favorites-empty-actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin-top: var(--space-4);
}

@media (min-width: 480px) {
  .favorites-empty-actions {
    flex-direction: row;
    justify-content: center;
  }

  .favorites-empty-actions .btn {
    width: auto;
    min-width: 200px;
  }
}

.favorites-generic-row {
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--space-3);
  text-align: center;
}

.favorites-generic-row .btn {
  width: auto;
  align-self: center;
}

.favorites-pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: var(--space-4);
}

.favorites-pagination .btn {
  width: auto;
  min-width: 120px;
}

.favorites-pagination-status {
  margin: 0;
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
}

.favorites-preview-notice {
  font-size: var(--font-size-sm);
  color: var(--color-text-muted);
  margin: 0 0 var(--space-3);
}

/* ---------------------------------------------------------------------
   Sales listing page (/sales)

   Every selector below is scoped to .page-sales or a .sales-* class that
   only the sales route renders, so /search, /favorites and the product
   detail page keep their existing behaviour unchanged. No new shadow and
   no new colour value is introduced here: the sale badge colours and every
   size/space used below come from the existing :root tokens.
   ------------------------------------------------------------------- */

.page-sales {
  /* .page defaults to --content-width (480px), which would squeeze the
     280px filter sidebar and the result grid into a single narrow column
     at >=900px. The sales listing uses the same catalog width as /search
     and the product detail page. */
  max-width: var(--catalog-width);
}

.page-sales h1 {
  font-size: var(--font-size-lg);
  margin: 0 0 var(--space-3);
}

.sales-methodology-notice {
  margin: 0 0 var(--space-3);
  font-size: var(--font-size-sm);
  line-height: var(--line-height-base);
}

.sales-methodology-confirmed-at {
  margin: var(--space-2) 0 0;
  font-weight: 600;
}

.sales-sort-note {
  margin: 0;
  font-size: var(--font-size-sm);
  line-height: var(--line-height-base);
}

/* .btn is width:100% so a primary action can fill a narrow column; inside
   the toolbar's flex row it has to size to its own label instead. */
.sales-apply-button {
  width: auto;
  flex: 0 0 auto;
}

/* Matches .search-results-grid: the grid sits inside .search-results-area,
   which is already bounded by the page and the 280px sidebar, so the
   catalog grid's own centring max-width must not narrow it further. */
.sales-results-grid {
  max-width: none;
}

.sales-card > * {
  min-width: 0;
}

/* The sales card current price reuses the shared .price-current cluster;
   this class only marks it for the sales-specific weight guarantee. */
.sales-card-current-price {
  margin: 0;
  font-weight: 700;
  line-height: var(--line-height-tight);
}

.sales-card-basis-note,
.sales-card-confirmed-at,
.sales-card-other-plans {
  margin: 0;
  font-size: var(--font-size-xs);
  line-height: var(--line-height-tight);
}

.sales-card-official-name {
  margin: 0;
  font-size: var(--font-size-xs);
  font-weight: 600;
  line-height: var(--line-height-tight);
  overflow-wrap: anywhere;
}

.sales-card-ends {
  margin: 0;
  font-size: var(--font-size-xs);
  line-height: var(--line-height-tight);
}

/* /sales keeps the 280px filter sidebar beside its results at >=900px, so the
   shared .catalog-grid step to 4 columns at that breakpoint would leave each
   card far narrower than the 190px the responsive source of truth allows for
   a sidebar layout. These two rules override the column count for the sales
   grid only -- they are more specific than .catalog-grid, so the global rule
   (and therefore /search, /favorites and the product detail page) is left
   exactly as it is. No new colour, shadow or fixed card width is introduced:
   the columns stay fractional so 320-1440px all reflow without overflow. */
@media (min-width: 900px) and (max-width: 1199px) {
  .page-sales .sales-results-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

@media (min-width: 1200px) {
  .page-sales .sales-results-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}
