/* LP parts kit v1 (2026-09-19). Pair with lp-parts.js. Catalog: references/parts-catalog.md
   Rules: content is fully readable without JS (enhancements live under html.lp-parts-on),
   never lock scrolling, never draw reader-facing text over a generated image. */

:root { --lp-ease: cubic-bezier(.2, .7, .2, 1); --lp-part-radius: 14px; }
[data-lp-part] img { display: block; max-width: 100%; height: auto; }

/* 1. reveal: image opens like a curtain when it enters the viewport */
.lp-parts-on [data-lp-part="reveal"] {
  clip-path: inset(0 0 100% 0); transform: translateY(18px);
  transition: clip-path .9s var(--lp-ease), transform .9s var(--lp-ease);
}
.lp-parts-on [data-lp-part="reveal"][data-lp-reveal="wipe"] { clip-path: inset(0 100% 0 0); transform: none; }
.lp-parts-on [data-lp-part="reveal"][data-lp-reveal="iris"] { clip-path: circle(0% at 50% 50%); transform: none; }
.lp-parts-on [data-lp-part="reveal"].is-in { clip-path: inset(0 0 0 0); transform: none; }
.lp-parts-on [data-lp-part="reveal"][data-lp-reveal="iris"].is-in { clip-path: circle(75% at 50% 50%); }

/* 2. depth: layered stills drift at different speeds. Put reader text only on a data-depth="0" layer */
[data-lp-part="depth"] { position: relative; overflow: hidden; border-radius: var(--lp-part-radius); }
[data-lp-part="depth"] > * { width: 100%; }
.lp-parts-on [data-lp-part="depth"] > *:not(:first-child) { position: absolute; inset: 0; height: 100%; object-fit: cover; }
.lp-parts-on [data-lp-part="depth"] > [data-depth]:not([data-depth="0"]) {
  transform: translate3d(0, calc(var(--lp-p, 0) * var(--lp-d, 0) * 70px), 0) scale(1.14); will-change: transform;
}
/* first child = a complete still that works alone (no JS, reduced motion). Layers above it are extras */
html:not(.lp-parts-on) [data-lp-part="depth"] > *:not(:first-child) { display: none; }

/* 3. compare: before/after slider driven by a real range input (keyboard and screen reader friendly) */
[data-lp-part="compare"] { position: relative; --pos: 50%; border-radius: var(--lp-part-radius); overflow: hidden; touch-action: pan-y; }
[data-lp-part="compare"] > img { width: 100%; }
.lp-parts-on [data-lp-part="compare"] > img:nth-of-type(2) { position: absolute; inset: 0; height: 100%; object-fit: cover; clip-path: inset(0 calc(100% - var(--pos)) 0 0); }
.lp-parts-on [data-lp-part="compare"]::after {
  content: ""; position: absolute; top: 0; bottom: 0; left: var(--pos); width: 2px; margin-left: -1px;
  background: #fff; box-shadow: 0 0 0 1px rgba(0,0,0,.25), 0 0 18px rgba(255,255,255,.7); pointer-events: none;
}
[data-lp-part="compare"] > input[type="range"] { display: none; }
.lp-parts-on [data-lp-part="compare"] > input[type="range"] {
  display: block; position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: ew-resize; touch-action: pan-y;
}
.lp-parts-on [data-lp-part="compare"] > input[type="range"]:focus-visible { opacity: 1; appearance: none; -webkit-appearance: none; background: transparent; outline: 3px solid Highlight; outline-offset: -3px; }
.lp-parts-on [data-lp-part="compare"] > input[type="range"]:focus-visible::-webkit-slider-thumb { -webkit-appearance: none; width: 1px; height: 1px; }
.lp-parts-on [data-lp-part="compare"] > input[type="range"]:focus-visible::-moz-range-thumb { width: 1px; height: 1px; border: 0; }

/* 4. foil: card tilts and a foil sheen follows the finger. Sheen is light only, no text */
[data-lp-part="foil"] { perspective: 900px; touch-action: pan-y; }
[data-lp-part="foil"] > * {
  position: relative; border-radius: var(--lp-part-radius); overflow: hidden;
  transform: rotateX(calc(var(--ry, 0) * -9deg)) rotateY(calc(var(--rx, 0) * 11deg));
  transition: transform .5s var(--lp-ease); box-shadow: 0 24px 50px -22px rgba(0,0,0,.55);
}
[data-lp-part="foil"].is-live > * { transition: none; }
.lp-parts-on [data-lp-part="foil"] > *::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; mix-blend-mode: soft-light; opacity: calc(var(--lp-sheen, 0) * .9);
  transition: opacity .4s;
  background:
    radial-gradient(circle at calc(50% + var(--rx, 0) * 50%) calc(50% + var(--ry, 0) * 50%), rgba(255,255,255,.5), transparent 38%),
    linear-gradient(calc(115deg + var(--rx, 0) * 40deg), transparent 30%, rgba(255,120,200,.5) 42%, rgba(120,220,255,.5) 50%, rgba(255,230,120,.5) 58%, transparent 70%);
}

/* 5. stack: cards pile up while you scroll (pure CSS sticky, never blocks scrolling) */
[data-lp-part="stack"] > * { margin-bottom: 28px; border-radius: var(--lp-part-radius); overflow: hidden; }
@supports (position: sticky) {
  .lp-parts-on [data-lp-part="stack"] > * { position: sticky; top: calc(14px + var(--lp-i, 0) * 16px); box-shadow: 0 -10px 30px -18px rgba(0,0,0,.5); }
}

/* 6. rail: swipe gallery with snap, each item opens in a dialog and returns to the same spot */
[data-lp-part="rail"]:where(:not([data-lp-rail="phone"])) {
  display: flex; gap: 14px; overflow-x: auto; scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch;
  padding: 4px max(16px, 8vw) 16px; scrollbar-width: none; overscroll-behavior-x: contain;
}
[data-lp-part="rail"]::-webkit-scrollbar { display: none; }
[data-lp-part="rail"]:where(:not([data-lp-rail="phone"])) > * { flex: 0 0 min(76%, 420px); scroll-snap-align: center; }
/* 6b. rail only on phones: data-lp-rail="phone" keeps the page's own grid on wider screens and turns it into one swipe row
   up to 600px (2026-09-27 AIパクくん5 HP v036: 8 big team cards stacked 4,579px tall on an iPhone). The next card peeks
   and the right edge fades until the end is reached; no rounded overflow:hidden parent (the edge cards would be cut round) */
@media (max-width: 600px) {
  [data-lp-part="rail"][data-lp-rail="phone"] {
    display: flex; gap: 14px; overflow-x: auto; scroll-snap-type: x mandatory; -webkit-overflow-scrolling: touch;
    padding-bottom: 8px; scrollbar-width: none; overscroll-behavior-x: contain;
  }
  [data-lp-part="rail"][data-lp-rail="phone"] > * { flex: 0 0 84%; min-width: 0; scroll-snap-align: start; }
  .lp-parts-on [data-lp-part="rail"][data-lp-rail="phone"]:not([data-lp-at-end]) {
    -webkit-mask-image: linear-gradient(90deg, #000 90%, transparent); mask-image: linear-gradient(90deg, #000 90%, transparent);
  }
}
[data-lp-zoom] { display: block; width: 100%; padding: 0; border: 0; background: none; cursor: zoom-in; border-radius: var(--lp-part-radius); overflow: hidden; }
dialog.lp-zoom { border: 0; padding: 0; background: transparent; max-width: 100vw; max-height: 100dvh; width: 100vw; height: 100dvh; overflow: auto; }
dialog.lp-zoom::backdrop { background: rgba(8,8,10,.92); }
dialog.lp-zoom img { width: min(100%, 1100px); margin: 56px auto 24px; }
dialog.lp-zoom .lp-zoom__close {
  position: fixed; top: 10px; right: 10px; min-width: 48px; min-height: 48px; border-radius: 24px; border: 1px solid rgba(255,255,255,.5);
  background: rgba(20,20,22,.8); color: #fff; font-size: 15px; padding: 0 16px; cursor: pointer;
}
html:has(dialog.lp-zoom[open]) { overflow: hidden; }

/* 7. ritual: a box the reader opens. If they scroll past, it opens by itself (no gate, no lock) */
[data-lp-part="ritual"] { position: relative; }
[data-lp-part="ritual"] .lp-ritual__frame { position: relative; display: block; width: 100%; padding: 0; border: 0; background: none; border-radius: var(--lp-part-radius); overflow: hidden; }
[data-lp-part="ritual"] .lp-ritual__frame > img { width: 100%; }
.lp-parts-on [data-lp-part="ritual"] .lp-ritual__frame { cursor: pointer; }
.lp-parts-on [data-lp-part="ritual"] .lp-ritual__frame > img:nth-of-type(2) { position: absolute; inset: 0; height: 100%; object-fit: cover; opacity: 0; transform: scale(1.04); transition: opacity .9s var(--lp-ease), transform 1.2s var(--lp-ease); }
.lp-parts-on [data-lp-part="ritual"].is-open .lp-ritual__frame > img:nth-of-type(2) { opacity: 1; transform: none; }
.lp-parts-on [data-lp-part="ritual"].is-open .lp-ritual__frame { cursor: default; }
.lp-parts-on [data-lp-part="ritual"]:not(.is-open) .lp-ritual__frame::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(circle at 50% 58%, rgba(255,226,150,.35), transparent 38%); animation: lp-breathe 2.6s ease-in-out infinite;
}
.lp-parts-on [data-lp-part="ritual"] .lp-ritual__inside { display: none; }
.lp-parts-on [data-lp-part="ritual"].is-unfolded .lp-ritual__inside { display: block; animation: lp-rise .8s var(--lp-ease) both; }
@keyframes lp-breathe { 50% { opacity: .35; } }
@keyframes lp-rise { from { opacity: 0; transform: translateY(16px); } }

/* 8. count: real numbers in HTML text count up once */
[data-lp-part="count"] { font-variant-numeric: tabular-nums; }

/* 9. dock: bottom call-to-action that appears after the first view and steps aside near the offer/form */
[data-lp-part="dock"] { display: none; }
.lp-parts-on [data-lp-part="dock"] {
  display: block; position: fixed; left: 0; right: 0; bottom: 0; z-index: 40; padding: 10px 16px calc(10px + env(safe-area-inset-bottom));
  transform: translateY(110%); transition: transform .45s var(--lp-ease); pointer-events: none;
}
.lp-parts-on [data-lp-part="dock"].is-in { transform: none; pointer-events: auto; }

/* 10. progress: thin reading progress bar */
.lp-parts-on [data-lp-part="progress"] {
  position: fixed; top: 0; left: 0; right: 0; height: 3px; z-index: 50; transform-origin: 0 50%;
  transform: scaleX(var(--lp-p, 0)); background: var(--lp-accent, #b4472e); pointer-events: none;
}

/* 11. scene: pinned stage where stills cross-fade as you scroll naturally (contain, never crop baked text) */
.lp-parts-on [data-lp-part="scene"].is-live { position: relative; height: calc(var(--lp-frames, 2) * 85svh); }
.lp-parts-on [data-lp-part="scene"].is-live .lp-scene__pin { position: sticky; top: 0; height: 100svh; overflow: hidden; }
.lp-parts-on [data-lp-part="scene"].is-live .lp-scene__pin > * { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; opacity: var(--lp-o, 0); transform: scale(calc(1.05 - var(--lp-o, 0) * .05)); will-change: opacity, transform; }

/* 12. spotlight: a dark mood image is lit where the finger or the scroll points. Do not hide essential copy in the dark */
[data-lp-part="spotlight"] { position: relative; border-radius: var(--lp-part-radius); overflow: hidden; touch-action: pan-y; }
.lp-parts-on [data-lp-part="spotlight"]::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(circle at calc(var(--mx, .5) * 100%) calc(var(--my, .3) * 100%), transparent 0 22%, rgba(4,6,14,.7) 58%);
}

/* 13. marquee: works flow sideways, pause when off screen. Falls back to a swipeable row */
[data-lp-part="marquee"] { overflow-x: auto; scrollbar-width: none; }
[data-lp-part="marquee"]::-webkit-scrollbar { display: none; }
[data-lp-part="marquee"] > .lp-marquee__track { display: flex; gap: 12px; width: max-content; }
.lp-parts-on [data-lp-part="marquee"].is-auto > .lp-marquee__track { padding-right: 12px; } /* keeps the loop seamless: half the track = one full set + its gap */
[data-lp-part="marquee"] > .lp-marquee__track > * { flex: 0 0 auto; height: clamp(120px, 34vw, 220px); width: auto; border-radius: 10px; }
.lp-parts-on [data-lp-part="marquee"].is-auto { overflow: hidden; }
.lp-parts-on [data-lp-part="marquee"].is-auto > .lp-marquee__track { animation: lp-marquee var(--lp-marquee-s, 38s) linear infinite; }
.lp-parts-on [data-lp-part="marquee"].is-off > .lp-marquee__track,
.lp-parts-on [data-lp-part="marquee"].is-held > .lp-marquee__track { animation-play-state: paused; }
@keyframes lp-marquee { to { transform: translateX(-50%); } }

/* Motion preference: show everything, move nothing */
@media (prefers-reduced-motion: reduce) {
  .lp-parts-on [data-lp-part="reveal"] { clip-path: none !important; transform: none !important; transition: none; }
  .lp-parts-on [data-lp-part="depth"] > [data-depth] { transform: none !important; }
  .lp-parts-on [data-lp-part="depth"] > *:not(:first-child) { display: none; }
  .lp-parts-on [data-lp-part="foil"] > * { transform: none; }
  .lp-parts-on [data-lp-part="ritual"] .lp-ritual__frame::after { animation: none; }
  .lp-parts-on [data-lp-part="ritual"] .lp-ritual__frame > img:nth-of-type(2) { transition: none; }
}

/* 14. pair: two things side by side to compare, also on phones (2026-09-27 HP v036: A/B banners were stacked, 1,911px tall).
   One column only below 360px. Keep choosers and captions short enough for half the width (the audit reports select_text_cut) */
[data-lp-part="pair"] { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(10px, 2.5vw, 22px); }
[data-lp-part="pair"] > * { min-width: 0; }
[data-lp-part="pair"] img { width: 100%; height: auto; }
@media (max-width: 360px) { [data-lp-part="pair"] { grid-template-columns: 1fr; } }
