/* ==========================================================================
   petmosaic.css — PetMosaic deep-zoom viewer (ENGINE-READY §3).

   Design language: concept-D. This file DECLARES NO PALETTE — it consumes the
   :root design tokens defined in site.css (SITE LAW): --clay/--sage/--ink/
   --paper/--muslin/--flax/--cream/--espresso/--gold, --font-display (Fraunces),
   --font-body (Mulish), --step-*, --r-*, --gutter, --shadow-*. Never invent a
   new colour here — that is the whole point of reusing the tokens.

   Two presentation modes, toggled by [data-mode] on .pm (petmosaic.js):
     split (default) — mosaic + paper card panel side by side.
     light            — mosaic near-fullbleed, glassy floating caption + controls.
   Fullscreen (.pm__float.is-fs, set by JS) forces the floating presentation and
   is styled independently of .pm because the float is reparented out of .pm into
   the OSD element on fullscreen (OSD 5 setFullPage DOM capture).
   ========================================================================== */

/* ---- Section shell: split grid by default, single column in light mode ---- */
.pm {
  position: relative;
  min-height: 100svh;
  background: var(--espresso);
  display: grid;
  grid-template-columns: minmax(0, 1.55fr) minmax(340px, 1fr);
  align-items: stretch;
}
.pm[data-mode="light"] { grid-template-columns: 1fr; }

/* ---- STAGE ---------------------------------------------------------------- */
.pm__stage-wrap {
  position: relative;
  min-height: 100svh;
  overflow: hidden;
  background: var(--espresso);
}
/* Warm underlay so the stage is never a black box before tiles load (concept-D poster) */
.pm__poster {
  position: absolute; inset: 0; z-index: 0;
  background:
    radial-gradient(120% 90% at 62% 34%, rgba(217,139,99,.35), transparent 60%),
    radial-gradient(90% 80% at 30% 70%, rgba(109,122,91,.28), transparent 62%),
    linear-gradient(160deg, #3a2a1c 0%, #2a2119 60%, #211a13 100%);
  animation: pmPosterDrift 26s ease-in-out infinite alternate;
  transform-origin: 60% 40%;
}
@keyframes pmPosterDrift { from { transform: scale(1.04); } to { transform: scale(1.16); } }

/* touch-action:none — the whole gesture goes to OSD (no page pinch fighting the viewer) */
.pm__stage {
  position: absolute; inset: 0; z-index: 1;
  touch-action: none;
  background: transparent;
  outline: none;
}
.pm__stage:focus-visible { box-shadow: inset 0 0 0 2px var(--clay-soft); }

/* ---- Loading spinner (frosted ring), removed once tiles paint --------------- */
.pm__spinner {
  position: absolute; z-index: 6; top: 50%; left: 50%;
  width: 54px; height: 54px; margin: -27px 0 0 -27px;
  display: grid; place-items: center;
  pointer-events: none;
  transition: opacity .4s ease;
}
.pm__ring {
  width: 44px; height: 44px; border-radius: 50%;
  border: 3px solid rgba(251,246,236,.28);
  border-top-color: var(--clay-soft);
  animation: pmSpin .8s linear infinite;
}
@keyframes pmSpin { to { transform: rotate(360deg); } }
.pm.is-ready .pm__spinner { opacity: 0; }

/* ---- Floating chrome (over the stage; reparented into OSD el on fullscreen) - */
.pm__float {
  position: absolute; inset: 0; z-index: 5;
  pointer-events: none;   /* let drags reach the mosaic; children re-enable pointer events */
}
.pm__float > * { pointer-events: auto; }

/* Glassy caption chip — shown in light mode and in fullscreen (.show-chip set by JS) */
.pm__chip {
  position: absolute;
  left: var(--gutter);
  top: clamp(5.2rem, 12vh, 7.5rem);   /* clear the fixed site header */
  max-width: min(30rem, 74vw);
  display: none;
  padding: 1.1rem 1.3rem 1.2rem;
  border-radius: var(--r-lg);
  color: var(--cream);
  background: color-mix(in srgb, var(--espresso) 52%, transparent);
  border: 1px solid rgba(251,246,236,.18);
  box-shadow: 0 24px 50px -30px rgba(0,0,0,.75);
  backdrop-filter: blur(16px) saturate(1.25);
  -webkit-backdrop-filter: blur(16px) saturate(1.25);
  animation: pmChipIn .5s cubic-bezier(.2,.8,.2,1);
}
@supports not (background: color-mix(in srgb, red, blue)) {
  .pm__chip { background: rgba(42,33,25,.72); }
}
.pm__float.show-chip .pm__chip { display: block; }
@keyframes pmChipIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.pm__chip-name { font-family: var(--font-display); font-weight: 460; font-size: var(--step-2); line-height: 1.05; margin: .3rem 0 0; }
.pm__chip-sub  { font-size: 0.95rem; line-height: 1.5; color: rgba(251,246,236,.86); margin: .6rem 0 0; }

/* Frosted round controls — bottom-right of the stage, always visible */
.pm__controls {
  position: absolute;
  right: var(--gutter);
  bottom: clamp(1.4rem, 3.5vh, 2.4rem);
  display: flex; gap: 0.55rem;
}
.pm__btn {
  width: 46px; height: 46px; flex: none;
  display: grid; place-items: center;
  border: 1px solid rgba(251,246,236,.22);
  border-radius: 50%;
  background: color-mix(in srgb, var(--espresso) 46%, transparent);
  color: var(--cream);
  cursor: pointer;
  -webkit-backdrop-filter: blur(12px) saturate(1.2);
  backdrop-filter: blur(12px) saturate(1.2);
  box-shadow: 0 12px 26px -16px rgba(0,0,0,.7);
  transition: background-color .2s, transform .2s, border-color .2s;
}
@supports not (background: color-mix(in srgb, red, blue)) {
  .pm__btn { background: rgba(42,33,25,.62); }
}
.pm__btn:hover { background: var(--clay); border-color: var(--clay); transform: translateY(-2px); }
.pm__btn:active { transform: translateY(0); }
.pm__btn:focus-visible { outline: 2px solid var(--clay-soft); outline-offset: 2px; }
.pm__btn svg {
  width: 20px; height: 20px; display: block;
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}

/* ---- Eyebrow (reuses the concept-D eyebrow rhythm, both on-dark and on-paper) */
.pm__eyebrow {
  font-family: var(--font-body);
  font-size: var(--step--1);
  font-weight: 700;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--clay-soft);
  display: inline-flex; align-items: center; gap: .7em;
}
.pm__eyebrow::before { content: ""; width: 1.9em; height: 2px; background: var(--clay-soft); display: inline-block; }
.pm__eyebrow--ink { color: var(--clay); }
.pm__eyebrow--ink::before { background: var(--clay); }

/* ---- CARD panel (split mode) --------------------------------------------- */
.pm__card {
  background: var(--paper);
  color: var(--ink);
  overflow-y: auto;
  display: flex; flex-direction: column; justify-content: center;
  border-left: 1px solid var(--line-ink);
}
.pm[data-mode="light"] .pm__card { display: none; }
.pm__card-inner {
  padding: clamp(6rem, 10vh, 8rem) clamp(1.6rem, 4vw, 3.2rem) clamp(2.5rem, 6vh, 4rem);
  max-width: 34rem;
}
.pm__card-name { font-family: var(--font-display); font-weight: 460; font-size: var(--step-4); line-height: 1.02; letter-spacing: -.02em; margin: .8rem 0 0; }
.pm__card-caption { font-size: var(--step-1); line-height: 1.5; color: var(--ink-soft); margin: 1.2rem 0 0; }
.pm__card-story { font-size: var(--step-0); line-height: 1.66; color: var(--ink-soft); margin: 1.1rem 0 0; max-width: 40ch; }
.pm__card-cta { margin: 2rem 0 0; }
.pm__card-hint { font-size: 0.85rem; color: var(--ink-faint); margin: 1.6rem 0 0; }
/* V7: сноска «нужна мозаика для своего проекта» — только на витрине (см. petmosaic.php).
   Отделена линией и приглушена: это НЕ второй призыв, главная кнопка карточки остаётся одна. */
.pm__card-aside {
  font-size: 0.82rem; line-height: 1.5; color: var(--ink-faint);
  margin: 1.1rem 0 0; padding-top: 1rem;
  border-top: 1px solid var(--line);
}
.pm__inline-toggle {
  background: none; border: 0; padding: 0; cursor: pointer;
  font: inherit; color: var(--clay); font-weight: 700;
  border-bottom: 1.5px solid var(--clay-soft);
}
.pm__inline-toggle:hover { color: var(--clay-deep); border-color: var(--clay); }

/* ==========================================================================
   FULLSCREEN — .pm__float carries .is-fs (set by JS on the OSD full-page event),
   because on fullscreen the float is reparented OUT of .pm into the OSD element,
   so [data-mode] selectors on .pm no longer reach it. inset:0 continues to cover
   the whole screen because the OSD element is the fullscreen positioned container.
   ========================================================================== */
.pm__float.is-fs { position: absolute; inset: 0; }
.pm__float.is-fs.show-chip .pm__chip { display: block; }

/* ==========================================================================
   RESPONSIVE — stack the split layout on narrow screens
   ========================================================================== */
@media (max-width: 860px) {
  .pm { grid-template-columns: 1fr; grid-template-rows: auto auto; min-height: auto; }
  .pm__stage-wrap { min-height: 64svh; }
  .pm__card { border-left: 0; border-top: 1px solid var(--line-ink); }
  .pm__card-inner { padding: clamp(2.4rem, 6vh, 3.4rem) var(--gutter) clamp(2.4rem, 6vh, 3.4rem); }
  .pm__controls { right: 1rem; bottom: 1rem; }
  /* 🔴 56 px, КАК НА ГЛАВНОЙ (09.09.2026). Было 42 px ≈ 7,4 мм — владелец про такие же кнопки:
     «очень маленькие, крохотные… человеку с большими пальцами очень тяжело будет нажимать».
     Этот файл стилей общий у `petmosaic.php` и у страницы клиента `/p`, поэтому правка выравнивает
     обе разом; на главной то же число задано в site.css. Три файла с одним размером — плохо, но
     развести их сейчас значило бы трогать вёрстку трёх страниц ради опрятности. Если однажды
     размер снова разойдётся — вот место, где искать второй экземпляр. */
  .pm__btn { width: 56px; height: 56px; }
  .pm__btn svg { width: 26px; height: 26px; }
  .pm__controls { gap: 14px; }
  .pm__chip { left: 1rem; right: 1rem; max-width: none; top: clamp(4.6rem, 11vh, 6rem); }
}

@media (prefers-reduced-motion: reduce) {
  .pm__poster { animation: none; }
  .pm__ring { animation-duration: 1.4s; }
  .pm__chip { animation: none; }
}

/* ---- The honest "not viewable" page (GAP-35) ------------------------------------------------
   Deliberately plain and quiet. It replaces a screen that used to show a stranger's dog with a
   stranger's name, so its whole job is to be calm, to say the fault is ours, and to leave one
   obvious next move — reply to the email. No CTA: an advert here reads as a shrug. */
.pm-unavailable { padding: 72px 0 96px; text-align: center; }
.pm-unavailable h1 { font-family: var(--font-display, Georgia, serif); font-size: clamp(30px, 5vw, 46px);
  margin: 0 0 18px; color: var(--ink, #23201c); }
.pm-unavailable p { margin: 0 auto 14px; max-width: 44ch; line-height: 1.65;
  color: var(--ink-soft, #5f574c); font-size: 17px; }
