/* Howler Scapes theme layer — field-journal component styles.
 * Companion to templates/partials/theme/kit.php (the PHP component functions) and
 * public/js/tailwind.config.js (tokens). Numbers come from the measured spec in
 * design/BRIEF-home-composition.md — change them there first.
 *
 * Z-scheme (BRIEF "Z-scheme"): 0 band color | 1 textures | 2 bleed art |
 * 10 content | 20 paper objects | 30 overlays (tape/stamps) | 40 header/logo.
 */

:root {
  --hs-parchment: #e7dbc2;
  --hs-paper-card: #ece3cd;   /* mockup-sampled card/note paper (lighter than pack sand) */
  --hs-cream-strip: #e2d5b6;  /* mockup-sampled newsletter strip */
  --hs-ink: #282d23;
  --hs-rust: #8d3f28;
  /* Paper-object shadows: a tight contact shadow + a long soft lift. */
  --hs-shadow-paper: 0 1px 2px rgba(40, 45, 35, 0.28), 0 22px 45px -18px rgba(40, 45, 35, 0.5);
  --hs-shadow-card: 0 1px 2px rgba(0, 0, 0, 0.25), 0 18px 34px -16px rgba(0, 0, 0, 0.55);
  --hs-shadow-overlay: 0 3px 8px rgba(40, 45, 35, 0.35);
}

/* ---- Display XL: Bebas Neue is width-correct for the mockup's condensed caps but a
 * touch light at poster sizes; the text-stroke thickens it to the mockup's print
 * weight (BRIEF "Type scale"). ---- */
.hs-display-xl {
  font-family: 'Bebas Neue', 'Oswald', sans-serif;
  text-transform: uppercase;
  line-height: 0.92;
  letter-spacing: 0.005em;
  -webkit-text-stroke: 1.2px currentColor;
}
.hs-display-lg {
  font-family: 'Bebas Neue', 'Oswald', sans-serif;
  text-transform: uppercase;
  line-height: 0.94;
  letter-spacing: 0.005em;
  -webkit-text-stroke: 0.8px currentColor;
}

/* Brush script (rust emotional lines) vs note script (ink annotations). */
.hs-script-brush { font-family: 'Kaushan Script', cursive; }
.hs-script-note  { font-family: 'Caveat', cursive; }

/* ---- Texture layers (kit: hs_texture()). Absolutely stacked, never in flow.
 * Sources are tex-*.svg mirrored-repeat patterns (scripts/build-texture-patterns.php):
 * the raw pack tiles are ~220px with edge vignetting and tile in visible rectangles;
 * the 2x2 mirrored cell makes every seam match by construction — continuous paper,
 * no grid (round-2 fix for the round-1 "quilted parchment" bug). ---- */
.hs-tex { position: absolute; inset: 0; pointer-events: none; }
.hs-tex--grain {
  background-image: url('/img/theme/tex-grain.svg');
  background-size: 920px auto;
  mix-blend-mode: multiply;
  opacity: 0.38;
}
.hs-tex--carto {
  /* Near-viewport scale: one mirrored cell ≈ the whole fold, so the map swirls read
   * as unique large cartography, never a repeating motif. */
  background-image: url('/img/theme/tex-carto.svg');
  background-size: 2500px auto;
  mix-blend-mode: multiply;
  opacity: 0.17;
}
.hs-tex--topo {
  background-image: url('/img/theme/tex-topo.svg');
  background-size: 1800px auto;
  opacity: 0.2;
}
.hs-tex--forest {
  background-image: url('/img/theme/tex-forest.svg');
  background-size: 1500px auto;
  mix-blend-mode: soft-light;
  opacity: 0.26;
}
.hs-tex--kraft {
  background-image: url('/img/theme/tex-kraft.svg');
  background-size: 880px auto;
  mix-blend-mode: multiply;
  opacity: 0.22;
}

/* ---- Paper objects ---- */
.hs-paper { background: var(--hs-paper-card); box-shadow: var(--hs-shadow-paper); }

.hs-taped-photo {
  background: #f2ead8;
  box-shadow: var(--hs-shadow-paper);
}

.hs-tape {
  position: absolute;
  z-index: 30;
  pointer-events: none;
  opacity: 0.9;
  filter: drop-shadow(0 2px 3px rgba(40, 45, 35, 0.25));
}

.hs-stamp { filter: drop-shadow(var(--hs-shadow-overlay)); }

/* Distressed double ring for the circular text stamp + card icon badges. */
.hs-ring-distress {
  position: relative;
}
.hs-ring-distress::after {
  content: '';
  position: absolute;
  inset: 4px;
  border: 1.5px dashed currentColor;
  border-radius: 9999px;
  opacity: 0.55;
  pointer-events: none;
}

/* Engraved illustrations sit IN the paper, not on it. */
.hs-engraving { mix-blend-mode: multiply; }

/* ---- Map bleed: feather the artwork into the parchment (no box, no border).
 * Wide soft ramps — a visible straight edge here is the "boxed map" failure. ---- */
.hs-map-bleed {
  mix-blend-mode: multiply;
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 16%, #000 100%),
    linear-gradient(to bottom, transparent 0, #000 13%, #000 88%, transparent 100%);
  mask-image: linear-gradient(to right, transparent 0, #000 16%, #000 100%),
    linear-gradient(to bottom, transparent 0, #000 13%, #000 88%, transparent 100%);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}

/* Rough painted rust line (newsletter bottom, mockup §6). */
.hs-brush-line {
  height: 7px;
  background: var(--hs-rust);
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 8' preserveAspectRatio='none'%3E%3Cpath d='M0 2.8 Q30 .4 70 2.2 T150 1.8 T230 3.2 T310 1.6 T400 2.6 L400 5.6 Q360 7.8 300 6.2 T190 6.8 T90 5.4 T0 6.4 Z' fill='%23000'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 8' preserveAspectRatio='none'%3E%3Cpath d='M0 2.8 Q30 .4 70 2.2 T150 1.8 T230 3.2 T310 1.6 T400 2.6 L400 5.6 Q360 7.8 300 6.2 T190 6.8 T90 5.4 T0 6.4 Z' fill='%23000'/%3E%3C/svg%3E");
  -webkit-mask-size: 400px 100%;
  mask-size: 400px 100%;
}

/* Imperfect "printed" border for rust buttons (mockup's BOOK YOUR ADVENTURE):
 * a thin light frame plus a second, slightly rotated inner pass — misregistered
 * print, not a crisp digital outline (DNA shape language). */
.hs-btn-print {
  position: relative;
  border: 1px solid rgba(242, 234, 216, 0.5);
}
.hs-btn-print::after {
  content: '';
  position: absolute;
  inset: 2.5px;
  border: 1px solid rgba(242, 234, 216, 0.32);
  border-radius: inherit;
  transform: rotate(-0.4deg) translateX(0.5px);
  pointer-events: none;
}

/* Themed text selection — rust ink on paper. */
::selection { background: var(--hs-rust); color: #f2ead8; }

/* Marker underline under script eyebrows (mockup's amber highlighter stroke). */
.hs-marker-underline {
  background-image: linear-gradient(100deg, rgba(141, 63, 40, 0.85), rgba(141, 63, 40, 0.55));
  background-repeat: no-repeat;
  background-size: 100% 3px;
  background-position: 0 96%;
  padding-bottom: 0.35em;
}

/* ============================ Motion layer ============================
 * 2026 magic, under the DNA's restraint law: field journal, never game UI.
 * public/js/theme-motion.js adds .hs-motion to <html> ONLY when the visitor does
 * not prefer reduced motion — without that class every reveal/draw rule below is
 * inert and the page renders fully static (also the no-JS fallback). Hover/press
 * transitions are gated behind the no-preference media query. All effects are
 * transform/opacity only: zero CLS, no scroll-jacking. */

/* The taped hero print straightens slightly when handled. */
.hs-photo-tilt { transform: rotate(2.5deg); }

@media (prefers-reduced-motion: no-preference) {
  .hs-photo-tilt { transition: transform 0.5s cubic-bezier(0.22, 0.61, 0.36, 1); }
  .hs-photo-tilt:hover { transform: rotate(1.3deg); }
  /* Card micro-interaction: lift + badge tick (photo scale rides the existing
   * Tailwind group-hover). */
  .hs-card { transition: transform 0.35s cubic-bezier(0.22, 0.61, 0.36, 1), box-shadow 0.35s ease; }
  .hs-card:hover { transform: translateY(-5px); }
  .hs-card .hs-ring-distress { transition: transform 0.35s ease; }
  .hs-card:hover .hs-ring-distress { transform: rotate(4deg); }
  /* Buttons press down 1px. */
  .hs-btn-print:active { transform: translateY(1px); }
}

/* Scroll reveals: gentle fade-rise on first entry. Rotated elements carry their
 * resting angle in --hs-rot (matching any Tailwind rotate class, which this rule
 * overrides while animating); --hs-rot0 sets a settle-from angle for stamps. */
.hs-motion [data-reveal] {
  opacity: 0;
  transform: translateY(var(--hs-rise, 18px)) rotate(var(--hs-rot0, var(--hs-rot, 0deg)));
  transition:
    opacity 0.7s cubic-bezier(0.22, 0.61, 0.36, 1),
    transform 0.7s cubic-bezier(0.22, 0.61, 0.36, 1);
}
.hs-motion [data-reveal].is-inview {
  opacity: 1;
  transform: translateY(0) rotate(var(--hs-rot, 0deg));
}

/* Map route: the rust dotted overlay draws itself along the artwork's baked route
 * when the section scrolls into view. The dotted paths sit behind an animating
 * solid-stroke mask; without .is-drawn (reduced motion / no JS) the overlay stays
 * hidden and the baked route alone shows. */
#hs-route .hs-rm { stroke-dasharray: 1; stroke-dashoffset: 1; }
#hs-route.is-drawn .hs-rm { stroke-dashoffset: 0; transition: stroke-dashoffset 1.9s ease-in-out; }
#hs-route.is-drawn .hs-rm-2 { transition-delay: 1.2s; transition-duration: 1.5s; }
#hs-route.is-drawn .hs-rm-3 { transition-delay: 2.1s; transition-duration: 0.9s; }
#hs-route .hs-ping { opacity: 0; transform-box: fill-box; transform-origin: center; }
#hs-route.is-drawn .hs-ping { animation: hsPing 0.9s ease-out forwards; }
@keyframes hsPing {
  0% { opacity: 0.75; transform: scale(0.35); }
  100% { opacity: 0; transform: scale(1.35); }
}

@media (prefers-reduced-motion: reduce) {
  .hs-hover-lift { transition: none !important; }
  /* The shell's Tailwind scroll-smooth class must also yield. */
  html { scroll-behavior: auto !important; }
}
