/* ============================================================
   Catapulte — css/brutaliste/animations.css
   Brutaliste skin: circular shutter overlay, per-character mask
   system for SplitText wave cascade, stroke initial state for
   em tags, reduced motion guards.

   Loaded as third brutaliste CSS file (after tokens + components).
   z-index hierarchy: content < grain 9998 < cursor 9999 < shutter 10000
   ============================================================ */

/* ── CIRCULAR SHUTTER OVERLAY ──
   Direct body child — required for iOS Safari clip-path + position:fixed
   stacking context compatibility (WebKit bug with transform ancestors).
   Hidden by default via visibility:hidden + collapsed clip-path.
   z-index 10000 sits above header (1000), cursor (9999), grain (9998).
   ──────────────────────────────────────────────────────────── */

.brut-shutter {
  position: fixed;
  inset: 0;
  background: var(--bg);            /* Adapts to active theme: #001219 dark / #f5f4ee light */
  z-index: 10000;
  visibility: hidden;
  pointer-events: none;
  clip-path: circle(0px at 50% 50%); /* Collapsed initial state */
}

/* ── NAVIGATED LOAD GATE STATE ──
   When html has page-transition-active, shutter covers full viewport.
   Gate 4 inline script sets this class before first paint when
   sessionStorage 'catapulte-transition' = 'entering'.
   CSS safety timeout: if JS never removes class, hide after 5s.
   ──────────────────────────────────────────────────────────── */

html.page-transition-active[data-skin="brutaliste"] .brut-shutter {
  visibility: visible;
  pointer-events: all;
  clip-path: circle(150vmax at 50% 50%); /* Fully covering — math: diagonal ≤ ~141.4vmax */
  animation: safety-fade-out 0s ease 5s forwards;
}

/* ── SPLITTEXT PER-CHARACTER MASK ──
   SplitText wraps each character in a <div class="char"> element.
   overflow:clip (NOT overflow:hidden) prevents creating a scroll
   container — aligns with established cinematic .mask-line pattern.
   display:inline-block required for overflow:clip on inline elements.
   yPercent animation in GSAP moves char below/above this boundary.
   ──────────────────────────────────────────────────────────── */

[data-skin="brutaliste"] .site-hero h1 .char,
[data-skin="brutaliste"] .page-hero h1 .char {
  overflow: clip;
  display: inline-block;
}

/* ── STROKE-ONLY INITIAL STATE FOR EM CHARS ──
   em tags within hero h1 start as stroke outlines (hollow text).
   GSAP animates -webkit-text-fill-color back to var(--text) as
   the wave cascade reaches those characters (stroke-to-fill phase).
   -webkit-text-stroke set in components.css on em elements;
   this overrides fill to transparent for the animated initial state.
   ──────────────────────────────────────────────────────────── */

[data-skin="brutaliste"] .site-hero h1 em .char,
[data-skin="brutaliste"] .page-hero h1 em .char {
  -webkit-text-stroke: 2px var(--accent);
  -webkit-text-fill-color: transparent;
  color: transparent;
}

/* ── CANVAS GRAIN OVERLAY (for Plan 02 — BRUT-06) ──
   Positioned above content but below cursor.
   opacity ~6%: subliminal texture felt more than seen.
   will-change: transform promotes to GPU compositing layer.
   width/height 100vw/vh prevents subpixel gaps on retina.
   ──────────────────────────────────────────────────────────── */

.brut-grain {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 9998;            /* Below cursor 9999 — grain must not block interaction */
  opacity: 0.06;            /* ~6% opacity: subliminal, felt not seen */
  will-change: transform;   /* Promote to GPU layer — avoids main-thread repaint */
  width: 100vw;
  height: 100vh;
}

/* ── BENTO GRID LAYOUT ──
   12-column asymmetric layout: row 1 = 8/4, row 2 = 6/6, row 3 = 4/8.
   Grid gap uses shared --card-gap token. Mobile collapses to single column.
   CSS toggles: brutaliste hides .services-list, cinematic hides .bento-grid.
   ──────────────────────────────────────────────────────────── */

[data-skin="brutaliste"] .bento-grid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: var(--card-gap, 1.5rem);
}

/* Row 1: 8 + 4 */
[data-skin="brutaliste"] .bento-card:nth-child(1) { grid-column: span 8; }
[data-skin="brutaliste"] .bento-card:nth-child(2) { grid-column: span 4; }

/* Row 2: 6 + 6 */
[data-skin="brutaliste"] .bento-card:nth-child(3) { grid-column: span 6; }
[data-skin="brutaliste"] .bento-card:nth-child(4) { grid-column: span 6; }

/* Row 3: 4 + 8 */
[data-skin="brutaliste"] .bento-card:nth-child(5) { grid-column: span 4; }
[data-skin="brutaliste"] .bento-card:nth-child(6) { grid-column: span 8; }

/* Mobile: single column */
@media (max-width: 767px) {
  [data-skin="brutaliste"] .bento-card { grid-column: span 12 !important; }
}

/* ── BENTO CARD HOVER-REVEAL PANEL ──
   Panel starts below the card boundary (translateY 100%), slides up on hover.
   overflow:hidden on card clips the panel during transition.
   min-height ensures cards have enough height for the reveal effect.
   Timing: 0.6s cubic-bezier(0.16, 1, 0.3, 1) — quick spring deceleration.
   ──────────────────────────────────────────────────────────── */

[data-skin="brutaliste"] .bento-card {
  position: relative;
  overflow: hidden;
  min-height: 220px;
}

[data-skin="brutaliste"] .bento-card__reveal {
  position: absolute;
  inset: 0;
  background: var(--accent);
  color: var(--bg);
  display: flex;
  align-items: flex-end;
  padding: var(--card-padding, 2rem);
  transform: translateY(100%);
  transition: transform 0.6s cubic-bezier(0.16, 1, 0.3, 1);
}

[data-skin="brutaliste"] .bento-card:hover .bento-card__reveal {
  transform: translateY(0);
}

/* ── SKIN EXCLUSIVITY: hide each layout on the opposing skin ──
   Brutaliste skin: show bento-grid, hide services-list.
   Default (cinematic): hide bento-grid — no data-skin attr on cinematic,
   so [data-skin="brutaliste"] .bento-grid override shows it only on brutaliste.
   ──────────────────────────────────────────────────────────── */

[data-skin="brutaliste"] .services-list { display: none; }
.bento-grid { display: none; }

/* ── BENTO CARD TOUCH-HOVER REVEAL ──
   On mobile touch, .touch-hover class triggers the reveal panel
   (mirrors :hover behavior for tap-to-hover pattern).
   ──────────────────────────────────────────────────────────── */

@media (max-width: 768px) {
  [data-skin="brutaliste"] .bento-card.touch-hover .bento-card__reveal {
    transform: translateY(0);
  }
}

/* ── REDUCED MOTION OVERRIDES ──
   All brutaliste animations respect prefers-reduced-motion.
   Shutter transitions are suppressed (JS guards also apply).
   Characters reveal immediately without wave cascade.
   ──────────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .brut-shutter {
    display: none !important;
  }

  [data-skin="brutaliste"] .site-hero h1 .char,
  [data-skin="brutaliste"] .page-hero h1 .char {
    overflow: visible;    /* No masking — chars always visible */
  }

  [data-skin="brutaliste"] .site-hero h1 em .char,
  [data-skin="brutaliste"] .page-hero h1 em .char {
    -webkit-text-stroke: 0;
    -webkit-text-fill-color: inherit;
    color: inherit;
  }

  .brut-grain {
    display: none;
  }
}
