/* Odyssey — paper, masks & ink. Owned by the PAPER/MASKS aesthetics agent. Loads after base.css.
   Assets: assets/masks/*.svg (torn-*, mat-*, scrap-*, edge-*, blot-*, splat-*), assets/textures/fibres.png.
   Regenerate the masks with: python3 tools/make_paper_assets.py
   Usage notes for slide agents:
   - .torn-1…8 / .blot-1…6 MASK the element itself (thematic images, .glyph figures, cutouts). Never on explicit images.
   - .torn-mat puts a torn paper MAT behind an untouched img / video / .clip; padding is the mat, nothing is cropped.
   - .splat-N: <span class="splat splat-3 rust" style="top:…;left:…;width:…"></span>; colour modifiers .ink .rust .cobalt .gold;
     intensity modifiers .faint / .bold. Sits behind text (z-index:-1 inside the isolated .slide).
   - Slides: alternating sheet tones + a torn top edge on every .slide after the first (uses .slide::before/::after). */

/* ------------------------------------------------------------------ paper sheets */
:root{
  --tex-grain:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .32 0 0 0 0 .24 0 0 0 0 .14 .8 0 0 0 -.33'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  --tex-fibres:url("../assets/textures/fibres.png"); /* same relative path works from css/ and slides/ */
}
body{
  background:var(--tex-fibres) 0 0 / 512px 512px, var(--tex-grain) 0 0 / 220px 220px, var(--paper);
}
.slide{
  --sheet:var(--paper);
  overflow-x:clip; /* splats may bleed past the sheet edge without causing sideways scroll; the torn lip still shows above */
  background:
    /* foxing: a few faint age stains, different per sheet (positions below) */
    radial-gradient(closest-side, color-mix(in srgb,var(--gold) 10%,transparent), transparent) var(--fox1, 88% 12%) / 260px 210px no-repeat,
    radial-gradient(closest-side, color-mix(in srgb,var(--rust) 6%,transparent), transparent) var(--fox2, 6% 92%) / 360px 270px no-repeat,
    radial-gradient(closest-side, color-mix(in srgb,var(--gold) 8%,transparent), transparent) var(--fox3, 64% 78%) / 110px 96px no-repeat,
    /* bottom shade, so the next sheet's torn lip has something to sit on */
    linear-gradient(180deg, transparent calc(100% - 90px), color-mix(in srgb,var(--paper-shade) 30%,transparent)),
    /* broad, seamless clouding of the paper body */
    radial-gradient(closest-side, color-mix(in srgb,var(--paper-shade) 24%,transparent), transparent) var(--cloud, 25% 40%) / 70% 70% no-repeat,
    radial-gradient(closest-side, color-mix(in srgb,var(--paper-shade) 18%,transparent), transparent) 85% 85% / 55% 55% no-repeat,
    var(--tex-fibres) 0 0 / 512px 512px,
    var(--tex-grain) 0 0 / 220px 220px,
    var(--sheet);
  /* very light side vignette: each slide reads as its own sheet (no top shade: the torn lip continues the sheet) */
  box-shadow:inset clamp(40px,6vw,110px) 0 clamp(50px,7vw,130px) calc(-1 * clamp(40px,6vw,110px)) color-mix(in srgb,var(--paper-shade) 45%,transparent),
             inset calc(-1 * clamp(40px,6vw,110px)) 0 clamp(50px,7vw,130px) calc(-1 * clamp(40px,6vw,110px)) color-mix(in srgb,var(--paper-shade) 45%,transparent);
}
.slide:nth-of-type(even){--sheet:var(--paper-light); --cloud:75% 45%; --fox1:10% 18%; --fox2:94% 86%; --fox3:30% 60%}
.slide:nth-of-type(3n){--fox1:72% 6%; --fox2:4% 40%; --fox3:90% 64%}

/* torn top edge: each sheet after the first overlaps the previous one.
   The lip carries the same textures, offset by its own height, so it is seamless with the sheet. */
.slide + .slide::before,
.slide + .slide::after{content:""; position:absolute; left:0; right:0; pointer-events:none;
  -webkit-mask:url("../assets/masks/edge-1.svg") center top / max(100%, 1400px) 100% no-repeat;
          mask:url("../assets/masks/edge-1.svg") center top / max(100%, 1400px) 100% no-repeat}
.slide + .slide::before{ /* the new sheet's ragged lip */
  top:-34px; height:48px; z-index:1;
  background:var(--tex-fibres) 0 34px / 512px 512px,
             var(--tex-grain) 0 34px / 220px 220px, var(--sheet);
}
.slide + .slide::after{ /* soft shadow the lip casts on the sheet beneath */
  top:-37px; height:51px; z-index:0;
  background:color-mix(in srgb,var(--ink) 16%,transparent);
}
.slide + .slide:nth-of-type(odd)::before,
.slide + .slide:nth-of-type(odd)::after{
  -webkit-mask-image:url("../assets/masks/edge-2.svg"); mask-image:url("../assets/masks/edge-2.svg");
}

/* ------------------------------------------------------------------ torn masks (mask the element itself) */
.torn-1,.torn-2,.torn-3,.torn-4,.torn-5,.torn-6,.torn-7,.torn-8,
.blot-1,.blot-2,.blot-3,.blot-4,.blot-5,.blot-6{
  clip-path:none; border-radius:0;
  -webkit-mask-position:center; mask-position:center;
  -webkit-mask-size:100% 100%; mask-size:100% 100%;
  -webkit-mask-repeat:no-repeat; mask-repeat:no-repeat;
}
.torn-1{-webkit-mask-image:url("../assets/masks/torn-1.svg"); mask-image:url("../assets/masks/torn-1.svg")}
.torn-2{-webkit-mask-image:url("../assets/masks/torn-2.svg"); mask-image:url("../assets/masks/torn-2.svg")}
.torn-3{-webkit-mask-image:url("../assets/masks/torn-3.svg"); mask-image:url("../assets/masks/torn-3.svg")}
.torn-4{-webkit-mask-image:url("../assets/masks/torn-4.svg"); mask-image:url("../assets/masks/torn-4.svg")}
.torn-5{-webkit-mask-image:url("../assets/masks/torn-5.svg"); mask-image:url("../assets/masks/torn-5.svg")}
.torn-6{-webkit-mask-image:url("../assets/masks/torn-6.svg"); mask-image:url("../assets/masks/torn-6.svg")}
.torn-7{-webkit-mask-image:url("../assets/masks/torn-7.svg"); mask-image:url("../assets/masks/torn-7.svg")}
.torn-8{-webkit-mask-image:url("../assets/masks/torn-8.svg"); mask-image:url("../assets/masks/torn-8.svg")}
.blot-1{-webkit-mask-image:url("../assets/masks/blot-1.svg"); mask-image:url("../assets/masks/blot-1.svg")}
.blot-2{-webkit-mask-image:url("../assets/masks/blot-2.svg"); mask-image:url("../assets/masks/blot-2.svg")}
.blot-3{-webkit-mask-image:url("../assets/masks/blot-3.svg"); mask-image:url("../assets/masks/blot-3.svg")}
.blot-4{-webkit-mask-image:url("../assets/masks/blot-4.svg"); mask-image:url("../assets/masks/blot-4.svg")}
.blot-5{-webkit-mask-image:url("../assets/masks/blot-5.svg"); mask-image:url("../assets/masks/blot-5.svg")}
.blot-6{-webkit-mask-image:url("../assets/masks/blot-6.svg"); mask-image:url("../assets/masks/blot-6.svg")}
/* blots are drawn in a square box: keep masked media square-ish unless the slide says otherwise */
:is(.blot-1,.blot-2,.blot-3,.blot-4,.blot-5,.blot-6) > :is(img,video,canvas){width:100%; height:100%; object-fit:cover}
:is(img,video,canvas):is(.blot-1,.blot-2,.blot-3,.blot-4,.blot-5,.blot-6){aspect-ratio:1; object-fit:cover}
/* a masked .scrap loses its rectangle shadow (the mask would cut it anyway) */
.scrap:is(.torn-1,.torn-2,.torn-3,.torn-4,.torn-5,.torn-6,.torn-7,.torn-8){box-shadow:none}

/* ------------------------------------------------------------------ torn paper MAT around an untouched picture */
.torn-mat, .scrap.torn-mat{
  position:relative; isolation:isolate; clip-path:none;
  background:transparent; box-shadow:none;
  padding:clamp(18px,3.8%,34px) clamp(18px,3.8%,34px) clamp(16px,3%,28px);
}
.torn-mat::before{
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  background:var(--paper-light) url("../assets/textures/fibres.png") 0 0 / 512px 512px;
  -webkit-mask:url("../assets/masks/mat-1.svg") 0 0 / 100% 100% no-repeat;
          mask:url("../assets/masks/mat-1.svg") 0 0 / 100% 100% no-repeat;
}
.torn-mat:nth-of-type(5n+2)::before{-webkit-mask-image:url("../assets/masks/mat-2.svg"); mask-image:url("../assets/masks/mat-2.svg")}
.torn-mat:nth-of-type(5n+3)::before{-webkit-mask-image:url("../assets/masks/mat-3.svg"); mask-image:url("../assets/masks/mat-3.svg")}
.torn-mat:nth-of-type(5n+4)::before{-webkit-mask-image:url("../assets/masks/mat-4.svg"); mask-image:url("../assets/masks/mat-4.svg")}
.torn-mat:nth-of-type(5n+5)::before{-webkit-mask-image:url("../assets/masks/mat-5.svg"); mask-image:url("../assets/masks/mat-5.svg")}
.torn-mat > img, .torn-mat > video, .torn-mat > .clip, .torn-mat > picture{
  display:block; width:100%; height:auto; -webkit-mask:none; mask:none; clip-path:none; border-radius:0;
  box-shadow:0 0 0 1px color-mix(in srgb,var(--ink) 10%,transparent);
}
.torn-mat > .clip{height:auto}
.torn-mat figcaption{margin-top:.7em; padding:0 .15em}
/* shadow: a filter on the mat (lists kept parallel so the base.css ink-in still animates) */
.torn-mat, .torn-mat[data-reveal].in, .paper-scrap, .paper-scrap[data-reveal].in{
  filter:blur(0) drop-shadow(0 9px 11px color-mix(in srgb,var(--ink) 20%,transparent));
}
.torn-mat[data-reveal]:not(.in), .paper-scrap[data-reveal]:not(.in){
  filter:blur(3px) drop-shadow(0 9px 11px transparent);
}

/* ------------------------------------------------------------------ paper scrap (marginalia note card) */
.paper-scrap{
  position:relative; isolation:isolate;
  padding:1.15em 1.35em 1.25em;
  color:var(--ink-soft);
}
.paper-scrap::before{
  content:""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  background:color-mix(in srgb,var(--paper-light) 62%,var(--paper-deep)) url("../assets/textures/fibres.png") 0 0 / 512px 512px;
  -webkit-mask:url("../assets/masks/scrap-1.svg") 0 0 / 100% 100% no-repeat;
          mask:url("../assets/masks/scrap-1.svg") 0 0 / 100% 100% no-repeat;
}
.paper-scrap:nth-of-type(even)::before{-webkit-mask-image:url("../assets/masks/scrap-2.svg"); mask-image:url("../assets/masks/scrap-2.svg")}
.slide:nth-of-type(odd) .paper-scrap::before{background-color:var(--paper-light)}
.paper-scrap h4{margin-top:0}
.paper-scrap > :last-child{margin-bottom:0}

/* ------------------------------------------------------------------ tape: translucent strip, torn ends */
.tape::after{
  top:-13px; width:clamp(70px,28%,112px); height:26px;
  background:color-mix(in srgb,var(--paper-shade) 58%,transparent);
  box-shadow:none; opacity:1; z-index:2;
  -webkit-mask:
    conic-gradient(from -135deg at right,#0000,#000 1deg 89deg,#0000 90deg) right / 51% 5px repeat-y,
    conic-gradient(from 45deg at left,#0000,#000 1deg 89deg,#0000 90deg) left / 51% 7px repeat-y;
          mask:
    conic-gradient(from -135deg at right,#0000,#000 1deg 89deg,#0000 90deg) right / 51% 5px repeat-y,
    conic-gradient(from 45deg at left,#0000,#000 1deg 89deg,#0000 90deg) left / 51% 7px repeat-y;
}
.tape.tape-l::after{left:12%; transform:rotate(-34deg)}
.tape.tape-r::after{left:auto; right:-22px; transform:rotate(38deg)}

/* ------------------------------------------------------------------ ink splats (decorative, behind text) */
.splat{
  position:absolute; display:block; pointer-events:none; z-index:-1;
  width:220px; height:auto; aspect-ratio:1;
  color:var(--ink); background:currentColor; opacity:.2; mix-blend-mode:multiply;
  -webkit-mask:url("../assets/masks/splat-1.svg") center / 100% 100% no-repeat;
          mask:url("../assets/masks/splat-1.svg") center / 100% 100% no-repeat;
}
.splat-2{aspect-ratio:10/7; color:var(--rust); opacity:.34; -webkit-mask-image:url("../assets/masks/splat-2.svg"); mask-image:url("../assets/masks/splat-2.svg")}
.splat-3{aspect-ratio:6/10; -webkit-mask-image:url("../assets/masks/splat-3.svg"); mask-image:url("../assets/masks/splat-3.svg")}
.splat-4{color:var(--rust); opacity:.42; -webkit-mask-image:url("../assets/masks/splat-4.svg"); mask-image:url("../assets/masks/splat-4.svg")}
.splat-5{aspect-ratio:2/1; color:var(--cobalt); opacity:.45; -webkit-mask-image:url("../assets/masks/splat-5.svg"); mask-image:url("../assets/masks/splat-5.svg")}
.splat-6{aspect-ratio:1000/360; opacity:.42; -webkit-mask-image:url("../assets/masks/splat-6.svg"); mask-image:url("../assets/masks/splat-6.svg")}
.splat.ink{color:var(--ink); opacity:.2}
.splat.rust{color:var(--rust); opacity:.38}
.splat.cobalt{color:var(--cobalt); opacity:.34}
.splat.gold{color:var(--gold); opacity:.4}
.splat.faint{opacity:.1}
.splat.bold{opacity:.62}
@media (max-width:820px){ .splat{max-width:55vw} }

/* ------------------------------------------------------------------ small refinements for unity */
.cutout{filter:drop-shadow(0 14px 16px color-mix(in srgb,var(--ink) 24%,transparent)) sepia(.14) contrast(1.02)}
.quote{border-left:0; padding-left:1.1em; position:relative}
.quote::before{ /* an inked, slightly uneven rule instead of a CSS border */
  content:""; position:absolute; left:0; top:.25em; bottom:.25em; width:3px; border-radius:2px;
  background:linear-gradient(180deg,transparent,var(--rust) 6%,var(--rust) 70%,color-mix(in srgb,var(--rust) 55%,transparent) 94%,transparent);
  transform:skewY(-2deg);
}
::selection{background:color-mix(in srgb,var(--rust) 22%,transparent)}
