/* Paper fray. The card's paper is a ::before run through the #paper-fray SVG filter (part.js injects it), so only
   the surface's edge roughens; the content on top stays sharp. Corners are barely eased (2px): it's a sheet, not
   a UI card. No border, no shadow; it's the frayed edge against the page that reads as paper.

   Knobs (custom properties on .fray or any ancestor):
     --fray-paper   the sheet's colour (#f2ede5 on a #ede8e1 page in the source; any colour or gradient works)
     --fray-radius  corner radius (2px)
     --fray-filter  which edge: url(#paper-fray) fine, url(#paper-fray-bold) rough; phones get bold by default
     --fray-inset   how far the sheet sits outside (negative) or inside the box (0)                              */
.fray {
  --fray-paper: #f2ede5;
  --fray-radius: 2px;
  --fray-filter: url(#paper-fray);
  --fray-inset: 0px;
  position: relative;        /* relative, not static: the ::before must anchor to the card (the source's note) */
  isolation: isolate;
}
.fray::before {
  content: "";
  position: absolute;
  inset: var(--fray-inset);
  z-index: -1;
  background: var(--fray-paper);
  border-radius: var(--fray-radius);
  filter: var(--fray-filter);
  pointer-events: none;
}
.fray--bold { --fray-filter: url(#paper-fray-bold); }

/* the source swaps every card to the rougher edge under 768px */
@media (max-width: 767px) {
  .fray { --fray-filter: url(#paper-fray-bold); }
}

/* path-wobble (off by default): Heron's hand-drawn line filter. class="path-wobble" on an svg, g, path or img.
   Quarter-pixel noise (baseFrequency 4, 3 octaves, seed 5387) pushes every stroke pixel up to +-1px (scale 2), so
   clean vector line art trembles like ink. Inside a scaled viewBox the numbers are in the svg's own units, so put it on
   the <svg> itself to keep the tremble at a CSS-pixel size. A perfectly straight horizontal or vertical <path> has a
   zero-height box and disappears under any SVG filter: put the class on its <svg> or <g> instead. */
.path-wobble { filter: url(#path-wobble); }
