/* ==========================================================================
   Crayon & paper lane (class prefix cr-). Site-wide micro-delight.
   Scope root: html.cr-paper (added in base.html; crayon-paper.js also adds it).
   One crayon filter (#cr-crayon) textures every crayon mark; the torn-paper filter
   (#cr-tear) shares its paper tooth. Both live in components/crayon_paper_defs.html.
   Colours: brand tokens only (var(--brand-*)). No layout changes: every addition is
   an absolutely positioned overlay, a paint-only property or a transform.
   ========================================================================== */

.cr-paper {
  --cr-grain-dark: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' seed='4' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  .5 0 0 0 -.25'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
  --cr-grain-light: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' seed='4' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  .7 0 0 0 -.3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
  --cr-ease-paper: cubic-bezier(.3, .7, .4, 1);
}

/* ------------------------------------------------------------------ crayon colours */
.cr-paper .cr-c-secondary { color: var(--brand-secondary); }
.cr-paper .cr-c-primary { color: var(--brand-primary); }
.cr-paper .cr-c-leaf { color: var(--brand-leaf); }
.cr-paper .cr-c-berry { color: var(--brand-berry); }
.cr-paper .cr-c-sky { color: var(--brand-sky); }
.cr-paper .cr-c-sun { color: var(--brand-sun); }

/* ------------------------------------------------------------------ 1. nav: crayon underline */
.cr-paper .cr-has-ul { position: relative; }
.cr-paper .cr-ul {
  position: absolute; left: .8rem; bottom: 2px; width: calc(100% - 1.6rem); height: 10px;
  overflow: visible; pointer-events: none; filter: url(#cr-crayon);
}
.cr-paper .nav-trigger .cr-ul { width: calc(100% - 2.75rem); }
.cr-paper .cr-ul path {
  fill: none; stroke: currentColor; stroke-width: 3.4; stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 1 2; stroke-dashoffset: 1.01;
  transition: stroke-dashoffset .2s ease-in;
}
.cr-paper .cr-has-ul:hover > .cr-ul path,
.cr-paper .cr-has-ul:focus-visible > .cr-ul path {
  stroke-dashoffset: 0; transition: stroke-dashoffset .42s cubic-bezier(.45, .05, .25, 1);
}
/* current page: drawn and staying drawn (replaces the foundation's flat bar only where the line exists) */
.cr-paper .nav-link.cr-has-ul[aria-current="page"] > .cr-ul path,
.cr-paper .nav-item.is-current > .cr-has-ul > .cr-ul path { stroke-dashoffset: 0; }
.cr-paper .nav-link.cr-has-ul[aria-current="page"],
.cr-paper .nav-item.is-current > .nav-trigger.cr-has-ul { box-shadow: none; }
/* the crayon line is the hover cue for plain links; the pill stays for an open submenu */
.cr-paper .nav-link.cr-has-ul:hover { background: none; }

/* footer link columns (navy): same crayon, sun colour, text sits a touch above it */
.cr-paper .site-footer .cr-has-ul:hover,
.cr-paper .site-footer .cr-has-ul:focus-visible { text-decoration: none; }
.cr-paper .site-footer .cr-ul { left: 0; width: 100%; bottom: -3px; height: 8px; }
.cr-paper .site-footer .cr-ul path { stroke-width: 3; }

/* mobile panel: the current page's label is underlined in crayon */
.cr-paper .cr-label { position: relative; display: inline-block; padding-bottom: 2px; }
.cr-paper .cr-label > .cr-ul { left: 0; width: 100%; bottom: -5px; height: 8px; }
.cr-paper .cr-label > .cr-ul path { stroke-dashoffset: 0; }

/* ------------------------------------------------------------------ 2. headings: hand-drawn crayon mark */
.cr-paper .squiggle { overflow: visible; filter: url(#cr-crayon); }
.cr-paper .squiggle path { stroke-width: 5; stroke-linecap: round; stroke-linejoin: round; }
.cr-paper .squiggle .cr-pass { stroke-width: 2.4; opacity: .5; transform: translate(1.3px, -1.2px); }
/* armed (by the JS, off screen): hidden with no transition, so arming never shows */
.cr-paper .squiggle.cr-armed path { stroke-dasharray: 1 2; stroke-dashoffset: 1.01; }
/* drawn: the transition lives here only, so it runs one way, once */
.cr-paper .squiggle.cr-armed.cr-drawn path {
  stroke-dashoffset: 0; transition: stroke-dashoffset 1.05s cubic-bezier(.55, .08, .3, 1) .12s;
}
.cr-paper .squiggle.cr-armed.cr-drawn .cr-pass { transition-duration: .9s; transition-delay: .5s; }
/* before the deferred JS arrives (html.js is set in <head>, before first paint) keep marks blank so
   a visible heading never shows the old mark, blinks out and redraws. Failsafe: if the lane JS never
   runs, they appear on their own after 2.5s. No JS at all (html.no-js) or reduced motion: never hidden. */
@media (prefers-reduced-motion: no-preference) {
  .js.cr-paper .squiggle:not(.cr-mark) path { opacity: 0; animation: cr-reveal 0s linear 2.5s forwards; }
}
@keyframes cr-reveal { to { opacity: 1; } }

/* ------------------------------------------------------------------ 3. buttons: thick paper */
.cr-paper .btn {
  background-image: var(--cr-grain-dark);
  background-size: 140px 140px;
  box-shadow: 0 4px 0 var(--btn-shadow), inset 0 1.5px 0 rgb(255 255 255 / .26), inset 0 -2px 0 rgb(0 0 0 / .07);
  transition: transform .16s var(--cr-ease-paper), box-shadow .16s var(--cr-ease-paper), background-color .2s ease, color .2s ease;
}
/* dark-text buttons get light fibres, so text contrast only ever goes up */
.cr-paper .btn-outline, .cr-paper .btn-sun { background-image: var(--cr-grain-light); }
.cr-paper .btn:hover, .cr-paper .btn:focus-visible {
  transform: translateY(-1px);
  box-shadow: 0 5px 0 var(--btn-shadow), inset 0 1.5px 0 rgb(255 255 255 / .3), inset 0 -2px 0 rgb(0 0 0 / .07);
}
.cr-paper .btn:active {
  transform: translateY(3px);
  box-shadow: 0 1px 0 var(--btn-shadow), inset 0 2px 3px rgb(0 0 0 / .16), inset 0 -1px 0 rgb(255 255 255 / .12);
  transition-duration: .05s;
}

/* ------------------------------------------------------------------ 4. cards: washi tape + gentle lift */
/* tape geometry + four rolls (defaults at low specificity so the roll rules below win) */
.cr-paper .card-lift, .cr-paper .quote-card {
  --cr-tape-l: 84px; --cr-tape-w: 24px; --cr-tape-c: 23px;
  --cr-tape-rgb: var(--brand-sun-rgb);
  --cr-tape-pat: repeating-linear-gradient(135deg, rgb(255 255 255 / .42) 0 3px, transparent 3px 8px);
  --cr-tape-pat-size: auto;
  --cr-tilt: .4deg;
}
.cr-paper .card-lift:nth-child(4n+2), .cr-paper .quote-card:nth-child(4n+2) {
  --cr-tape-rgb: var(--brand-primary-rgb);
  --cr-tape-pat: radial-gradient(circle, rgb(255 255 255 / .62) 0 1.5px, transparent 2px);
  --cr-tape-pat-size: 7px 7px;
}
.cr-paper .card-lift:nth-child(4n+3), .cr-paper .quote-card:nth-child(4n+3) {
  --cr-tape-rgb: var(--brand-berry-rgb);
  --cr-tape-pat: repeating-linear-gradient(0deg, rgb(255 255 255 / .38) 0 1.5px, transparent 1.5px 6px);
}
.cr-paper .card-lift:nth-child(4n+4), .cr-paper .quote-card:nth-child(4n+4) {
  --cr-tape-rgb: var(--brand-leaf-rgb);
  --cr-tape-pat: repeating-linear-gradient(90deg, rgb(255 255 255 / .34) 0 5px, transparent 5px 11px);
}
.cr-paper .card-lift:nth-child(even), .cr-paper .quote-card:nth-child(even) { --cr-tilt: -.3deg; }
@media (max-width: 639px) {
  .cr-paper .card-lift, .cr-paper .quote-card { --cr-tape-l: 66px; --cr-tape-w: 20px; --cr-tape-c: 17px; }
}
.cr-paper .card-lift:not(.doc-card):not(.paper-grain):not(.cr-no-tape)::before,
.cr-paper .quote-card:not(.cr-no-tape)::before {
  content: ""; position: absolute; z-index: 4; pointer-events: none;
  width: var(--cr-tape-l); height: var(--cr-tape-w);
  left: calc(var(--cr-tape-c) - var(--cr-tape-l) / 2); top: calc(var(--cr-tape-c) - var(--cr-tape-w) / 2);
  transform: rotate(-41deg);
  background-color: rgb(var(--cr-tape-rgb) / .6);
  background-image:
    linear-gradient(180deg, rgb(255 255 255 / .38), rgb(255 255 255 / 0) 45%, rgb(0 0 0 / .05)),
    var(--cr-tape-pat),
    var(--cr-grain-light);
  background-size: auto, var(--cr-tape-pat-size), 140px 140px;
  clip-path: polygon(0 0, 100% 0, 97.2% 16%, 100% 31%, 96.8% 49%, 99.6% 66%, 97% 83%, 100% 100%, 0 100%, 2.6% 85%, 0 69%, 3.1% 52%, .2% 35%, 2.8% 17%);
}
/* every second card: a short strip across the top edge instead of the corner, so tapes on
   neighbouring cards never bunch up in the gap between them. The strip is lifted with a transform,
   not a negative top: its layout box stays inside the card, so CSS columns (testimonials) never
   split it off into the previous column. */
.cr-paper .card-lift:not(.doc-card):not(.paper-grain):not(.cr-no-tape):nth-child(even)::before,
.cr-paper .quote-card:not(.cr-no-tape):nth-child(even)::before {
  width: calc(var(--cr-tape-l) * .86); left: calc(50% - var(--cr-tape-l) * .43); top: 0;
  transform: translateY(calc(var(--cr-tape-w) * -.45)) rotate(-3.5deg);
}
/* tape must be able to cross the card edge: lift the clip on the two cards that had one,
   and clip their inner pieces (photo, corner blob) exactly where the card used to */
.cr-paper .program-card:not(.cr-no-tape) { overflow: visible; }
/* the corner blob used to hang 30px/40px outside the card and rely on that clip; redraw the same
   visible quarter inside the card (same circle: r 60px, centre 30px in from the right, 20px up) */
.cr-paper .program-card:not(.cr-no-tape)::after {
  inset: auto 0 0 auto; width: 90px; height: 80px; border-radius: 0 0 var(--radius-lg) 0;
  background: radial-gradient(circle 60px at 60px 60px, var(--hue-soft) calc(100% - .5px), transparent 100%);
}
.cr-paper .post-card:not(.cr-no-tape) { overflow: visible; }
.cr-paper .post-card:not(.cr-no-tape) .post-img { border-radius: calc(var(--radius-lg) - 1px) calc(var(--radius-lg) - 1px) 0 0; }

/* lift: the card hangs from its tape, so it swings a hair around the taped corner */
.cr-paper .card-lift:not(.doc-card):not(.paper-grain):not(.cr-no-tape) {
  transform-origin: var(--cr-tape-c) var(--cr-tape-c);
  transition: transform .32s var(--cr-ease-paper), box-shadow .32s ease;
}
.cr-paper .card-lift:not(.doc-card):not(.paper-grain):not(.cr-no-tape):nth-child(even) {
  transform-origin: 50% 0;
}
.cr-paper .card-lift:not(.doc-card):not(.paper-grain):not(.cr-no-tape):hover,
.cr-paper .card-lift:not(.doc-card):not(.paper-grain):not(.cr-no-tape):focus-within {
  transform: translateY(-3px) rotate(var(--cr-tilt));
}

/* ------------------------------------------------------------------ 5. dividers: torn paper */
.cr-paper .divider:not(.cr-no-tear) svg { overflow: visible; filter: url(#cr-tear); }

/* flat-edged full-width bands (no wave divider): a strip in the colour OUTSIDE the band straddles
   each flat edge and is torn by the same filter, so the edge wanders a few px either side of where it
   was (band keeps its size; the strip's solid part lies over the neighbouring section's padding,
   same colour, invisible). Today: the blog post's related-posts band and the home enroll ribbon.
   Strip geometry: 20px box, edge 7px in, solid 13px (the filter needs > 11.5px of solid). */
.cr-paper main > .section[class*="tint-"]:not(.cr-no-tear),
.cr-paper main > .section-tight[class*="tint-"]:not(.cr-no-tear),
.cr-paper #enroll-ribbon .ribbon:not(.cr-no-tear) { position: relative; --cr-edge-c: var(--brand-paper); }
.cr-paper main > .section[class*="tint-"]:not(.cr-no-tear)::before,
.cr-paper main > .section[class*="tint-"]:not(.cr-no-tear)::after,
.cr-paper main > .section-tight[class*="tint-"]:not(.cr-no-tear)::before,
.cr-paper main > .section-tight[class*="tint-"]:not(.cr-no-tear)::after,
.cr-paper #enroll-ribbon .ribbon:not(.cr-no-tear)::before,
.cr-paper #enroll-ribbon .ribbon:not(.cr-no-tear)::after {
  content: ""; position: absolute; left: 0; right: 0; height: 20px; pointer-events: none;
  background: linear-gradient(to bottom, transparent 7px, var(--cr-edge-c) 7px);
  filter: url(#cr-tear);
}
.cr-paper main > .section[class*="tint-"]:not(.cr-no-tear)::before,
.cr-paper main > .section-tight[class*="tint-"]:not(.cr-no-tear)::before,
.cr-paper #enroll-ribbon .ribbon:not(.cr-no-tear)::before { top: -13px; transform: scaleY(-1); }
.cr-paper main > .section[class*="tint-"]:not(.cr-no-tear)::after,
.cr-paper main > .section-tight[class*="tint-"]:not(.cr-no-tear)::after,
.cr-paper #enroll-ribbon .ribbon:not(.cr-no-tear)::after { bottom: -13px; }

/* ------------------------------------------------------------------ reduced motion: final state, no movement */
@media (prefers-reduced-motion: reduce) {
  .cr-paper .cr-ul path, .cr-paper .cr-has-ul:hover > .cr-ul path, .cr-paper .cr-has-ul:focus-visible > .cr-ul path { transition: none; }
  .cr-paper .btn, .cr-paper .btn:hover, .cr-paper .btn:focus-visible, .cr-paper .btn:active { transform: none; transition: none; }
  .cr-paper .card-lift:not(.doc-card):not(.paper-grain):not(.cr-no-tape),
  .cr-paper .card-lift:not(.doc-card):not(.paper-grain):not(.cr-no-tape):hover,
  .cr-paper .card-lift:not(.doc-card):not(.paper-grain):not(.cr-no-tape):focus-within { transform: none; transition: none; }
}
@media print {
  .cr-paper .squiggle path { stroke-dashoffset: 0 !important; transition: none !important; }
  .cr-paper .card-lift::before, .cr-paper .quote-card::before,
  .cr-paper main > [class*="tint-"]::before, .cr-paper main > [class*="tint-"]::after,
  .cr-paper #enroll-ribbon .ribbon::before, .cr-paper #enroll-ribbon .ribbon::after { display: none; }
}
