/* ==========================================================================
   HAVEN — marketing page styles
   Built on the HAVEN design system (styles.css + tokens/).
   Only vanilla CSS. No frameworks.
   ========================================================================== */

/* --------------------------------------------------------------------------
   PALETTE OVERRIDE — no blues on this site.
   The design system ships a sky/denim blue, but the HAVEN logo is pink,
   green and yellow only, so this page stays inside those three (plus the
   red-crayon accent, cream paper, and ink). Blue textures were recolored
   to green; the sky tokens are remapped here rather than edited in
   tokens/colors.css, so the shared design system stays intact.
   -------------------------------------------------------------------------- */
:root {
  --rule-gap: 30px;                /* spacing of the ruled lines, and the
                                      line-height of every line of body copy */
  --rule-offset: 22px;             /* nudges the ruling onto the baseline */
  --yellow-soft: #fdefc0;          /* soft tint the system was missing */
  --sky:      var(--green);        /* was #8fb3d9 */
  --sky-soft: var(--yellow-soft);  /* was #d3e4f2 */
  --denim:    #2f4a2c;             /* deep forest, matches the footer texture */
  --brand-info: var(--green);
  --focus-ring: var(--red-crayon); /* readable against pink, green and yellow */
  --tape-ink: #2f2a20;             /* dark pencil, for writing on top of tape */
}

/* --- reset ---------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;

  /* Always reserve the scrollbar track, so a short page and a long one are the
     same width. */
  scrollbar-gutter: stable;
  overflow-y: scroll;          /* same effect where scrollbar-gutter is unsupported */

  /* The striped paper lives here, not on <body>. When body both owns the page
     background and carries overflow-x: hidden, the background's sizing area
     follows body's own scroll extent, so it rendered at a different scale from
     one page to the next. On <html> it is anchored to the canvas everywhere.
     The tile is 420x740 and seamless both ways, so it just repeats. */
  background-color: var(--paper-cream);
  background-image: url('assets/textures/striped-paper-brand.jpg');
  background-size: 420px auto;
  background-repeat: repeat;
}
body, h1, h2, h3, h4, p, ul, ol, figure, blockquote { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img { max-width: 100%; display: block; }
button, input, textarea, select { font: inherit; color: inherit; }
a { color: inherit; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
  }
}

/* --- page ----------------------------------------------------------------- */
/* the body is the desk the notebook is lying on — a shade deeper than the
   pages, so the white sheets read as paper sitting on top of it */
body {
  font-family: var(--font-body);
  /* every line of Gaegu is one size and exactly one ruled line tall, so the
     writing sits on the paper instead of drifting across it */
  font-size: var(--text-body-lg);
  line-height: var(--rule-gap);
  color: var(--text-body);
  background: transparent;     /* the paper is on <html> */
  overflow-x: hidden;
}

body::before {
  content: '';
  position: fixed;
  inset: 0;
  background: var(--paper-cream);
  opacity: .18;
  z-index: -1;
  pointer-events: none;
}

/* scroll stays locked while the notebook is still opening */
body.is-loading { overflow: hidden; }

/* ==========================================================================
   THE NOTEBOOK COVER  (loading screen)
   ========================================================================== */
.book { display: none; }

.js .book {
  display: grid;
  place-items: center;
  position: fixed;
  inset: 0;
  z-index: 200;
  background-color: var(--paper-cream);
  background-image: url('assets/textures/striped-paper-brand.jpg');
  background-size: 420px auto;
}

.book__scene {
  position: relative;
  width: min(330px, 58vw);
  aspect-ratio: 736 / 951;
  perspective: 1700px;
  transform: scale(.96);
  animation: book-settle 700ms var(--ease-bounce) both;
}

@keyframes book-settle {
  from { transform: scale(.86) translateY(14px); opacity: 0; }
  to   { transform: scale(.96) translateY(0);    opacity: 1; }
}

/* the first page, waiting underneath the cover */
.book__page {
  position: absolute;
  inset: 0;
  background-color: #fffdf8;
  background-image:
    linear-gradient(to right, transparent 0 13%, rgba(212,81,74,.5) 13% calc(13% + 1.5px), transparent calc(13% + 1.5px)),
    repeating-linear-gradient(to bottom, transparent 0 15px, rgba(123,161,93,.3) 15px 16px);
  border-radius: 2px 8px 8px 2px;
  box-shadow: inset 14px 0 18px -14px rgba(74,64,50,.5), 0 10px 26px rgba(74,64,50,.22);
}

.book__cover {
  position: absolute;
  inset: 0;
  transform-origin: left center;
  transform: rotateY(0deg);
  transform-style: preserve-3d;
  border-radius: 3px 9px 9px 3px;
  overflow: hidden;
  box-shadow: 0 12px 30px rgba(74,64,50,.34);
  transition: transform 1150ms cubic-bezier(.62,.02,.2,1),
              box-shadow 1150ms var(--ease-out);
}
.book__cover img { width: 100%; height: 100%; object-fit: cover; }

/* a paper label taped over the printed one */
.book__label {
  position: absolute;
  left: 31.5%;
  top: 15.5%;
  width: 44%;
  min-height: 24%;
  display: grid;
  align-content: center;
  justify-items: center;
  gap: 2px;
  padding: 3% 2%;
  background: #fffdf8;
  border: 2px solid var(--ink);
  border-radius: 12px;
  box-shadow: 1px 2px 0 rgba(74,64,50,.5);
  transform: rotate(-2deg);
  text-align: center;
}
.book__label-kicker {
  font-family: var(--font-hand);
  font-size: clamp(.5rem, 1.5vw, .62rem);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.book__label-name {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 5.5vw, 2.4rem);
  line-height: 1;
  color: var(--ink);
}
.book__label-sub {
  font-family: var(--font-hand);
  font-size: clamp(.5rem, 1.4vw, .6rem);
  color: var(--ink-soft);
}

/* two scraps of washi holding the label down */
.book__tape {
  position: absolute;
  width: 17%;
  height: 5.5%;
  background-image: url('assets/textures/tape-green.jpg');
  background-size: auto 100%;
  opacity: .95;
}
.book__tape--tl { left: 28%; top: 13.5%; transform: rotate(-24deg); }
.book__tape--br { left: 62%; top: 36%;   transform: rotate(-24deg); }

/* --- the opening --------------------------------------------------------- */
.book.is-open .book__cover {
  transform: rotateY(-162deg);
  box-shadow: 0 22px 44px rgba(74,64,50,.16);
}
.book.is-open .book__scene { animation: book-lean 1150ms var(--ease-out) both; }

@keyframes book-lean {
  from { transform: scale(.96); }
  to   { transform: scale(1.06); }
}

.book.is-gone {
  opacity: 0;
  visibility: hidden;
  transition: opacity 520ms var(--ease-out), visibility 0s 520ms;
}

/* someone who prefers less motion just gets the site */
@media (prefers-reduced-motion: reduce) {
  .js .book { display: none; }
}

.container {
  width: min(100% - var(--space-5) * 2, var(--container-width));
  margin-inline: auto;
}

/* sections sit directly under one another — one blank ruled line between */
/* gaps between sections step by whole ruled lines, so every line of writing
   keeps landing between the rules on the paper */
.section { padding-block: 0; margin-top: calc(var(--rule-gap) * 2); }
.section--tight { padding-block: 0; }

/* ==========================================================================
   THE SHEET — one continuous page of looseleaf per page of the site.
   All the content sits on a single piece of paper: the ruling, the red
   margin rule and the stitched binding run unbroken from top to bottom.
   ========================================================================== */
.sheet {
  --sheet-margin: 78px;          /* where the red margin rule falls */

  position: relative;
  background-color: #fffdf8;
  padding: 60px var(--space-7) 60px calc(var(--sheet-margin) + var(--space-4));
  border-radius: 3px;
  box-shadow:
    0 1px 0 rgba(74,64,50,.18),
    0 14px 28px -18px rgba(74,64,50,.55),
    inset 22px 0 26px -26px rgba(74,64,50,.35);   /* shadow near the binding */
}

/* the ruling itself — behind the content, never on top of it */
.sheet::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  border-radius: inherit;
  background-image:
    /* red margin rule */
    linear-gradient(to right,
      transparent 0 var(--sheet-margin),
      rgba(212,81,74,.42) var(--sheet-margin),
      rgba(212,81,74,.42) calc(var(--sheet-margin) + 1.5px),
      transparent calc(var(--sheet-margin) + 1.5px)),
    /* horizontal rules */
    repeating-linear-gradient(to bottom,
      transparent 0 calc(var(--rule-gap) - 1px),
      rgba(123,161,93,.22) calc(var(--rule-gap) - 1px),
      rgba(123,161,93,.22) var(--rule-gap));
  background-position: 0 0, 0 var(--rule-offset);
}

/* stitched binding down the left edge */
.sheet::after {
  content: '';
  position: absolute;
  left: 26px;
  top: var(--space-6);
  bottom: var(--space-6);
  width: 2px;
  z-index: 0;
  pointer-events: none;
  background-image: repeating-linear-gradient(to bottom,
    var(--ink-soft) 0 9px, transparent 9px 19px);
  opacity: .4;
}

/* content rides above the ruling */
.sheet > * { position: relative; z-index: 1; }

/* one continuous sheet per page: the ruling, margin rule and stitched binding
   run unbroken from the top of the content to the bottom */
.sheet > .section:first-child,
.sheet > .hero:first-child { margin-top: 0; }
/* the first block on the afternoons page sits a line higher up the paper */
.sheet > #day:first-child { margin-top: -18px; }
/* Meet the Team opens the about page — lift it the same way */
.sheet > #team:first-child { margin-top: -8px; }

/* sections are just spacing now — they carry no paper of their own */
.sheet > section { position: relative; z-index: 1; }

/* --- typography ----------------------------------------------------------- */
h1, h2, h3, h4 {
  font-family: var(--font-display);
  color: var(--text-heading);
  line-height: var(--leading-tight);
  font-weight: 400;
}
.display-xl { font-size: var(--text-display-xl); }
.display-lg { font-size: var(--text-display-lg); }
.display-md { font-size: var(--text-display-md); }
.heading-md { font-size: var(--text-heading-md); font-family: var(--font-display); }

/* .lede used to be the larger size — now it just constrains the measure */
.lede { max-width: 58ch; }

/* one size for every line of body copy on the paper */
.sheet p,
.sheet li,
.sheet blockquote,
.sheet label,
.sheet input,
.sheet textarea,
.sheet select {
  font-size: var(--text-body-lg);
  line-height: var(--rule-gap);
}

/* paragraphs step by whole ruled lines, so the rhythm never breaks */
.sheet p + p { margin-top: var(--rule-gap); }
.muted { color: var(--ink-soft); }
.eyebrow {
  font-family: var(--font-hand);
  font-size: var(--text-label);
  letter-spacing: var(--tracking-wide);
  color: var(--ink-soft);
}

/* skip link */
.skip-link {
  position: absolute;
  left: var(--space-4);
  top: -100px;
  z-index: 100;
  background: var(--yellow);
  color: var(--ink);
  border: 2.5px solid var(--ink);
  border-radius: var(--radius-pill);
  padding: var(--space-2) var(--space-4);
  transition: top var(--duration-fast) var(--ease-out);
}
.skip-link:focus { top: var(--space-4); }

/* consistent focus treatment */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible {
  outline: 3px solid var(--focus-ring);
  outline-offset: 3px;
}

/* --- buttons: strips of washi tape ---------------------------------------- */
/*
   Every button is a piece of tape stuck to the page: real scanned tape as the
   background, hand-torn ends, a slight tilt, and a soft shadow so it sits on
   the paper rather than floating above it.

   The tape lives on ::before rather than the button itself. Clipping the torn
   ends would also clip the keyboard focus ring, so the button box stays a plain
   rectangle and only the pseudo-element gets cut.
*/
.btn {
  position: relative;
  isolation: isolate;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  font-family: var(--font-hand);
  font-weight: 700;
  font-size: var(--text-body-md);
  letter-spacing: var(--tracking-wide);
  text-decoration: none;
  cursor: pointer;
  border: none;
  border-radius: 0;
  background: none;
  padding: var(--space-3) var(--space-6);
  color: var(--tape-ink);
  text-shadow: 0 1px 0 rgba(255, 253, 246, .55);
  transform: rotate(-1.2deg);
  transition:
    transform var(--duration-med) var(--ease-bounce),
    filter var(--duration-med) var(--ease-out);
}

.btn::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -2;
  background-image: var(--tape, url('assets/textures/tape-cream.jpg'));
  background-repeat: repeat-x;
  background-position: center;
  background-size: auto 100%;
  /* hand-torn left and right ends */
  clip-path: polygon(
    3px 0%, calc(100% - 2px) 0%,
    calc(100% - 5px) 17%, 100% 38%,
    calc(100% - 3px) 60%, calc(100% - 1px) 82%,
    calc(100% - 4px) 100%, 2px 100%,
    5px 79%, 0px 57%, 4px 33%, 1px 15%
  );
  filter: drop-shadow(1px 2px 2px rgba(74, 64, 50, .3));
  transition: filter var(--duration-med) var(--ease-out);
}

/* --- the corner peels ------------------------------------------------------
   On hover the top-right corner lifts and folds back over the tape, the way a
   piece of washi does when you start picking at it. The flap is a triangle
   folded along the diagonal, so it covers exactly the patch it came from —
   no need to fake a hole in the tape underneath.
   -------------------------------------------------------------------------- */
.btn::after {
  content: '';
  position: absolute;
  top: -1px;
  right: -1px;
  width: 26px;
  height: 26px;
  z-index: -1;
  pointer-events: none;
  /* the triangle: fold runs top-left to bottom-right, tip at top-right */
  clip-path: polygon(100% 0, 0 0, 100% 100%);
  /* dark along the fold, catching the light out at the lifted tip */
  background-image: linear-gradient(45deg,
    rgba(126, 114,  94, .82)  0%,
    rgba(214, 203, 180, .92) 34%,
    rgba(253, 250, 240, .97) 68%,
    rgba(255, 253, 246, .99) 100%);
  filter: drop-shadow(-2px 3px 2px rgba(74, 64, 50, .32));
  transform-origin: 100% 0;
  transform: scale(.05) rotate(-14deg);
  opacity: 0;
  transition:
    transform 300ms var(--ease-bounce),
    opacity 140ms var(--ease-out);
}

.btn:hover::after,
.btn:focus-visible::after {
  transform: scale(1) rotate(0deg);
  opacity: 1;
}
.btn--lg::after { width: 32px; height: 32px; }
.btn--sm::after { width: 20px; height: 20px; }

/* pressing it puts the corner back down */
.btn:active::after { transform: scale(.55) rotate(-6deg); transition-duration: 90ms; }

/* hover: the tape lifts and settles straighter, like it's being repositioned */
.btn:hover { transform: translateY(-2px) rotate(.4deg); }
.btn:hover::before { filter: drop-shadow(2px 4px 4px rgba(74, 64, 50, .34)); }
.btn:active { transform: translateY(1px) rotate(-1.2deg) scale(.97); }
.btn:active::before { filter: drop-shadow(1px 1px 1px rgba(74, 64, 50, .3)); }

.btn:disabled { opacity: .5; cursor: not-allowed; transform: none; }
.btn:disabled::before { filter: none; }
.btn:disabled::after { display: none; }

/* no peeling for anyone who asked for less motion */
@media (prefers-reduced-motion: reduce) {
  .btn::after { display: none; }
}

/* the focus ring needs the unclipped button box, so it is drawn here */
.btn:focus-visible { outline: 3px solid var(--focus-ring); outline-offset: 4px; }

.btn--primary   { --tape: url('assets/textures/tape-pink.jpg'); }
.btn--accent    { --tape: url('assets/textures/tape-yellow.jpg'); transform: rotate(1.4deg); }
.btn--ghost     { --tape: url('assets/textures/tape-cream.jpg'); }
.btn--secondary {
  --tape: url('assets/textures/tape-green.jpg');
  color: var(--paper);
  text-shadow: 0 1px 2px rgba(28, 34, 20, .85);
}
.btn--accent:hover  { transform: translateY(-2px) rotate(-.4deg); }
.btn--accent:active { transform: translateY(1px) rotate(1.4deg) scale(.97); }

.btn--lg { font-size: var(--text-body-lg); padding: var(--space-4) var(--space-7); }
.btn--sm { font-size: var(--text-body-sm); padding: var(--space-2) var(--space-5); }

/* --- cards ---------------------------------------------------------------- */
.card {
  background: var(--surface-card);
  border: 2.5px solid var(--border-ink);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-crayon);
  padding: var(--space-5);
}
.card--lg { border-radius: var(--radius-lg); padding: var(--space-6); }
.card--cream { background: var(--paper-cream); }
.card--pink  { background: var(--pink-soft); }
.card--green { background: var(--green-soft); }
.card--yellow { background: var(--yellow-soft); }

/* hand-placed tilt — applied to some cards, never all */
.tilt-1 { transform: rotate(var(--rotate-sticker-1)); }
.tilt-2 { transform: rotate(var(--rotate-sticker-2)); }
.tilt-3 { transform: rotate(var(--rotate-sticker-3)); }

.card.wobble {
  transition: transform var(--duration-med) var(--ease-bounce),
              box-shadow var(--duration-med) var(--ease-out);
}
.card.wobble:hover { transform: translateY(-4px) rotate(-1.5deg); box-shadow: 4px 6px 0 var(--ink); }
.card.tilt-2.wobble:hover { transform: translateY(-4px) rotate(2.5deg); }

/* --- sticker label (washi tape) ------------------------------------------- */
.sticker {
  display: inline-block;
  font-family: var(--font-hand);
  font-weight: 700;
  font-size: var(--text-label);
  color: var(--ink);
  padding: var(--space-1) var(--space-4);
  border: 2px solid var(--ink);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-crayon-sm);
  background-image: url('assets/textures/washi-tape-green-gingham.jpg');
  background-size: cover;
  background-position: center;
  transform: rotate(-4deg);
}
.sticker--yellow { background-image: none; background-color: var(--yellow); }
.sticker--pink   { background-image: none; background-color: var(--pink-soft); transform: rotate(3deg); }

/* --- badges / tags -------------------------------------------------------- */
.tag {
  display: inline-block;
  font-family: var(--font-hand);
  font-size: var(--text-body-sm);
  padding: 2px var(--space-3);
  border: 2px solid var(--ink);
  border-radius: var(--radius-pill);
  background: var(--paper-cream);
}

/* --- doodles -------------------------------------------------------------- */
/* source illustrations sit on white paper — multiply drops them onto cream */
.doodle { mix-blend-mode: multiply; }

/* ==========================================================================
   NAV
   ========================================================================== */
.nav {
  position: relative;
  z-index: 20;
  padding-block: var(--space-4);
  border-bottom: 2.5px dashed var(--border-soft);
  background: rgba(255, 253, 246, .9);
}
.nav__inner {
  display: flex;
  align-items: center;
  gap: var(--space-6);
}
.nav__brand {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  text-decoration: none;
  margin-right: auto;
}
.nav__logo { width: 54px; height: 54px; object-fit: contain; }
.nav__lockup { height: 44px; width: auto; }
.nav__wordmark {
  font-family: var(--font-display);
  font-size: var(--text-heading-md);
  color: var(--ink);
  line-height: 1;
}
.nav__links {
  display: flex;
  align-items: center;
  gap: var(--space-5);
}
.nav__link {
  font-family: var(--font-hand);
  font-size: var(--text-body-md);
  text-decoration: none;
  color: var(--ink);
  padding-bottom: 2px;
  border-bottom: 2.5px solid transparent;
  transition: border-color var(--duration-fast) var(--ease-out),
              transform var(--duration-med) var(--ease-bounce);
}
.nav__link:hover { border-bottom-color: var(--pink); transform: translateY(-2px) rotate(-1deg); }

/* the page you're on is underlined in crayon and sits a touch heavier */
.nav__link.is-current {
  border-bottom-color: var(--green);
  border-bottom-style: solid;
  font-weight: 700;
}

.nav__toggle {
  display: none;
  background: #fff;
  border: 2.5px solid var(--ink);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-crayon-sm);
  padding: 6px 10px;
  cursor: pointer;
  font-family: var(--font-hand);
}
.nav__toggle-bars { display: block; width: 22px; }
.nav__toggle-bars span {
  display: block;
  height: 2.5px;
  background: var(--ink);
  border-radius: 2px;
  margin: 4px 0;
}

/* ==========================================================================
   HERO
   ========================================================================== */
.hero { padding-block: 0; position: relative; }
.hero__grid {
  display: grid;
  grid-template-columns: 1.05fr .95fr;
  gap: var(--space-8);
  align-items: center;
}
/* the copy column now carries the problem list too, so it needs its own rhythm */
.hero__copy > * + * { margin-top: var(--rule-gap); }
.hero__title { margin-bottom: var(--space-4); }
.hero__title em { font-style: normal; color: var(--pink); }
.hero__mission {
  margin-block: var(--space-4) var(--space-6);
  padding-left: var(--space-4);
  border-left: 4px solid var(--green);
}
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--space-4); align-items: center; }
.hero__note { font-size: var(--text-body-sm); color: var(--ink-soft); margin-top: var(--space-4); }

.hero__art { position: relative; display: grid; justify-items: start; align-items: center; align-self: center; }
.hero__art-card {
  background: #fff;
  border: 2.5px solid var(--ink);
  border-radius: var(--radius-lg);
  box-shadow: 4px 6px 0 var(--ink);
  padding: var(--space-4);
  transform: rotate(2deg);
  max-width: 380px;
}
.hero__art-card img { border-radius: var(--radius-sm); }
.hero__sticker {
  position: absolute;
  top: -18px;
  left: 4%;
  z-index: 2;
}
.hero__art-mini {
  position: absolute;
  bottom: -34px;
  /* anchored to the logo rather than the right edge, so it follows it left */
  left: 62%;
  right: auto;
  width: 128px;
  background: #fff;
  border: 2.5px solid var(--ink);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-crayon);
  padding: 6px;
  transform: rotate(-6deg);
}

/* ==========================================================================
   SECTION HEADERS
   ========================================================================== */
.section-head { max-width: 62ch; margin-bottom: var(--space-7); }
.section-head .eyebrow { display: block; margin-bottom: var(--space-2); }
.section-head p { margin-top: var(--space-3); font-size: var(--text-body-lg); }

/* ==========================================================================
   ABOUT
   ========================================================================== */

.about__text p + p { margin-top: var(--space-4); }

/* ==========================================================================
   PROGRAM PILLARS
   ========================================================================== */
.pillars {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-6);
}
/* let the heading, the intro line and the cards breathe. Both gaps are whole
   multiples of the ruled line, so the writing keeps landing between the rules. */
/* the display heading's own line box isn't a whole ruled line tall, which
   left this paragraph sitting hard against a rule — nudge it clear. */
#day h2 { margin-bottom: calc(var(--rule-gap) - 11px); }
/* tighter under the prongs heading. Kept at zero rather than a half-line so the
   paragraph below still lands between the rules on the paper. */
#programs h2 { margin-bottom: 0; }
/* the prongs sit a little closer to the schedule above them */
#programs { margin-top: 44px; }
#programs > div > p { margin-bottom: var(--rule-gap); }
#programs .pillars { margin-top: 0; }
.pillar { display: flex; flex-direction: column; }
.pillar__art {
  border: 2.5px solid var(--ink);
  border-radius: var(--radius-sm);
  overflow: hidden;
  margin-bottom: var(--space-4);
  aspect-ratio: 4 / 3;
}
.pillar__art img { width: 100%; height: 100%; object-fit: cover; }
.pillar h3 { font-size: var(--text-heading-lg); margin-bottom: var(--space-2); }
.pillar p { margin-bottom: var(--space-4); }
.pillar__list { margin-top: auto; display: flex; flex-wrap: wrap; gap: var(--space-2); }

/* ==========================================================================
   LISTENING / NEEDS ASSESSMENT
   ========================================================================== */
.listen__grid {
  display: grid;
  grid-template-columns: .85fr 1.15fr;
  gap: var(--space-8);
  align-items: start;
}

.pull-quote {
  background: var(--pink-soft);
  position: sticky;
  top: var(--space-5);
}
.pull-quote blockquote {
  font-family: var(--font-display);
  font-size: var(--text-heading-lg);
  line-height: var(--leading-snug);
  color: var(--ink);
}
.pull-quote figcaption {
  margin-top: var(--space-4);
  font-size: var(--text-body-md);
  color: var(--ink-soft);
}

.stat-list { display: grid; gap: var(--space-4); margin-top: var(--space-5); }
.stat-list li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-4);
  align-items: center;
  padding: var(--space-4) var(--space-5);
}
.stat-list__value {
  font-family: var(--font-display);
  font-size: var(--text-heading-lg);
  color: var(--green-deep);
  line-height: 1;
}

/* ==========================================================================
   TEAM
   ========================================================================== */
.team {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-6);
}
.team__card { display: flex; flex-direction: column; gap: var(--space-3); }
.team__card h3 { font-size: var(--text-heading-lg); }
.team__card .tag { align-self: flex-start; background: var(--green-soft); }
/* childhood photos, square so the three cards line up whatever the original
   aspect ratio was */
.team__photo {
  width: 100%;
  aspect-ratio: 1;
  object-fit: cover;
  border: 2.5px solid var(--ink);
  border-radius: var(--radius-sm);
  margin-bottom: var(--space-2);
}


/* ==========================================================================
   GET INVOLVED
   ========================================================================== */
.involve {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-6);
}
.involve__card { display: flex; flex-direction: column; gap: var(--space-3); }
.involve__card h3 { font-size: var(--text-heading-lg); }
.involve__card ul { display: grid; gap: var(--space-2); }
.involve__card li { display: flex; gap: var(--space-2); font-size: var(--text-body-sm); }
.involve__card li::before { content: '✦'; color: var(--green-deep); flex: 0 0 auto; }
.involve__card .btn { margin-top: auto; align-self: flex-start; }

/* ==========================================================================
   DONATE BAND
   ========================================================================== */
.donate { text-align: center; }
.donate__panel {
  max-width: 720px;
  margin-inline: auto;
  background: var(--paper);
  text-align: center;
}
.donate__panel p { margin-block: var(--space-4) var(--space-6); font-size: var(--text-body-lg); }
.donate__actions { display: flex; gap: var(--space-4); justify-content: center; flex-wrap: wrap; }

/* the caregiver quote under the donate button — no box, and set at exactly
   the same size as the paragraph above it */
.donate__quote {
  margin: var(--space-6) auto 0;
  max-width: 62ch;
}
.donate__quote blockquote {
  font-family: var(--font-body);
  font-size: var(--text-body-lg);
  line-height: var(--rule-gap);
  color: var(--text-body);
}
.donate__quote figcaption {
  margin-top: var(--rule-gap);
  font-family: var(--font-display);
  font-size: var(--text-display-md);
  line-height: var(--leading-snug);
  color: var(--ink-soft);
}

/* the legal notes live on the paper below the panel, quieter than the rest */
.donate__legal {
  max-width: 62ch;
  margin: var(--space-5) auto 0;
  text-align: center;
  font-size: var(--text-body-sm) !important;
  line-height: var(--leading-normal) !important;
  color: var(--ink-soft);
}

/* ==========================================================================
   CONTACT
   ========================================================================== */
.contact__grid {
  display: grid;
  grid-template-columns: .85fr 1.15fr;
  gap: var(--space-8);
  align-items: start;
}
.contact__aside p + p { margin-top: var(--space-4); }
.contact__detail {
  margin-top: var(--space-5);
  display: grid;
  gap: var(--space-3);
  font-size: var(--text-body-md);
}
.contact__detail strong { font-family: var(--font-hand); color: var(--ink); }

.form { display: grid; gap: var(--space-5); }
.field { display: grid; gap: var(--space-2); }
.field > label {
  font-family: var(--font-hand);
  font-weight: 700;
  color: var(--ink);
  font-size: var(--text-body-md);
}
.field input,
.field textarea,
.field select {
  font-family: var(--font-body);
  font-size: var(--text-body-md);
  background: #fff;
  border: 2.5px solid var(--ink);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  box-shadow: var(--shadow-crayon-sm);
  transition: transform var(--duration-fast) var(--ease-out);
}
.field textarea { resize: vertical; min-height: 130px; }
.field input:focus, .field textarea:focus, .field select:focus { transform: translateY(-1px); }
.field[data-invalid='true'] input,
.field[data-invalid='true'] textarea,
.field[data-invalid='true'] select { border-color: var(--red-crayon); }
.field__error {
  font-size: var(--text-body-sm);
  color: var(--red-crayon);
  min-height: 0;
  display: none;
}
.field[data-invalid='true'] .field__error { display: block; }

.form__row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-5); }
.form__foot { display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap; }
.form__note { font-size: var(--text-body-sm); color: var(--ink-soft); }

/* toast */
.toast {
  position: fixed;
  left: 50%;
  bottom: var(--space-6);
  transform: translate(-50%, 200%) rotate(-1.5deg);
  background: var(--yellow);
  border: 2.5px solid var(--ink);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-crayon);
  padding: var(--space-3) var(--space-6);
  font-family: var(--font-hand);
  font-weight: 700;
  color: var(--ink);
  z-index: 60;
  /* Parking it with a percentage translate left a sliver of the rounded top
     edge above the bottom of the window. Hiding it outright means the height
     maths can never leak it again. */
  opacity: 0;
  visibility: hidden;
  transition:
    transform var(--duration-med) var(--ease-bounce),
    opacity var(--duration-fast) var(--ease-out),
    visibility 0s var(--duration-med);
}
.toast.is-visible {
  transform: translate(-50%, 0) rotate(-1.5deg);
  opacity: 1;
  visibility: visible;
  transition:
    transform var(--duration-med) var(--ease-bounce),
    opacity var(--duration-fast) var(--ease-out),
    visibility 0s;
}

/* ==========================================================================
   FOOTER
   ========================================================================== */
.footer {
  background-image: url('assets/textures/forest-stars-pattern.jpg');
  background-size: 300px;
  border-top: 3px solid var(--ink);
  padding-block: var(--space-8);
  color: var(--paper);
}
.footer__panel {
  background: var(--paper);
  color: var(--text-body);
  display: grid;
  grid-template-columns: 1.2fr 1fr 1fr;
  gap: var(--space-6);
}
.footer__brand { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-3); }
.footer__brand img { width: 60px; }
.footer__name {
  font-family: var(--font-display);
  font-size: var(--text-heading-sm);
  line-height: var(--leading-tight);
  color: var(--text-heading);
}
.footer h4 { font-size: var(--text-heading-sm); margin-bottom: var(--space-3); }
.footer__list { display: grid; gap: var(--space-2); font-size: var(--text-body-sm); }
.footer__list a { text-decoration: none; border-bottom: 2px solid transparent; }
.footer__list a:hover { border-bottom-color: var(--pink); }
.footer__legal {
  margin-top: var(--space-6);
  text-align: center;
  font-size: var(--text-body-sm);
  color: var(--paper-cream);
  text-shadow: 0 1px 3px rgba(24, 46, 22, .85);
}

/* ==========================================================================
   SCROLL REVEAL
   ========================================================================== */
.reveal { opacity: 0; transform: translateY(18px); }
.reveal.is-in {
  opacity: 1;
  transform: none;
  transition: opacity 500ms var(--ease-out), transform 500ms var(--ease-out);
}
/* keep the hand-placed tilts once revealed */
.reveal.tilt-1.is-in { transform: rotate(var(--rotate-sticker-1)); }
.reveal.tilt-2.is-in { transform: rotate(var(--rotate-sticker-2)); }
.reveal.tilt-3.is-in { transform: rotate(var(--rotate-sticker-3)); }

@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; }
}

/* ==========================================================================
   HOME PAGE
   ========================================================================== */
/* the three problems, hand-numbered down the margin */
.numbered {
  display: grid;
  gap: 2px;
  margin-top: var(--space-4);
  max-width: 56ch;
}
.numbered li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-3);
  align-items: center;
  font-size: var(--text-body-lg);
  /* the list runs tighter than the ruled body copy around it */
  line-height: var(--leading-snug);
}
.numbered__n {
  /* two flat paper stars layered, one pair of brand colours each, number on top */
  font-family: var(--font-display);
  font-size: var(--text-heading-md);
  line-height: 1;
  /* darker than the body ink so the digit reads against the star */
  color: var(--tape-ink);
  width: 54px;
  height: 54px;
  display: grid;
  place-items: center;
  background: url('assets/shapes/star-yellow.svg') center / contain no-repeat;
  text-shadow: 0 1px 0 rgba(255, 253, 246, .7);
}
.numbered li:nth-child(2) .numbered__n { background-image: url('assets/shapes/star-pink.svg'); }
.numbered li:nth-child(3) .numbered__n { background-image: url('assets/shapes/star-green.svg'); }

/* the three objectives */
.objective { display: flex; flex-direction: column; gap: var(--space-4); }
.objective .tag {
  align-self: flex-start;
  font-weight: 700;
  background: var(--paper-cream);
}
.objective p { font-size: var(--text-body-lg); }

/* the closing statement, set on a dashed note card.
   Drawn in CSS rather than stretched from the image: a dashed rounded
   rectangle is exactly what CSS borders do, so the dashes stay evenly spaced
   and the corners keep their radius at every width. Colours sampled from the
   reference: #fdf3e7 paper, #ad8951 stitching. */
.closing-line {
  font-family: var(--font-display) !important;
  font-size: var(--text-display-md) !important;
  line-height: var(--leading-snug) !important;
  color: var(--text-heading);

  width: min(100%, 74ch);
  margin: var(--space-8) auto 0;
  padding: var(--space-7) var(--space-7);
  text-align: center;

  /* soft pink ground with a fine staggered dot grid, drawn as two offset
     radial-gradient tiles rather than an image, so it stays crisp at any size */
  background-color: #ffe8e7;
  background-image:
    radial-gradient(circle 2.4px at 50% 50%, rgba(74, 64, 50, .12) 96%, transparent 100%),
    radial-gradient(circle 2.4px at 50% 50%, rgba(74, 64, 50, .12) 96%, transparent 100%);
  background-size: 26px 26px;
  background-position: 0 0, 13px 13px;
  border: 3px dashed var(--pink);
  border-radius: 34px;
}

/* ==========================================================================
   CUT-OUT DOODLES
   These drawings have had their white paper knocked out, so they sit straight
   on the page like stickers instead of inside a white frame.
   ========================================================================== */
.art-bare {
  background: none;
  border: none;
  box-shadow: none;
  padding: 0;
  max-width: 340px;
}
.art-bare img { border-radius: 0; }

/* The HAVEN mark in the hero runs much larger than the other cut-outs.
   It uses logo-mark.png — the same logo with its transparent margin trimmed
   off, so the artwork fills the box instead of floating in 35% empty space. */
.hero__art-card.art-bare {
  max-width: 100%;
  align-self: center;   /* sits level with the headline and paragraph */
}

.cutout {
  /* the frames used multiply to hide their white box — a cut-out doesn't
     need it, and multiply would only muddy the colours against the paper */
  mix-blend-mode: normal;
  filter: drop-shadow(1px 3px 2px rgba(74, 64, 50, .22));
}

/* ==========================================================================
   ONE SIZE FOR EVERY LINE OF GAEGU
   Body copy was set at three different sizes depending on where it sat.
   Every line of running text is now the same size and exactly one ruled
   line tall, so nothing looks shrunken next to its neighbours.

   Chips keep their small size on purpose — tags, the eyebrow labels and the
   sticker labels are labels, not prose.
   ========================================================================== */
.sheet p,
.sheet li,
.sheet blockquote,
.sheet figcaption,
.sheet label,
.sheet input,
.sheet textarea,
.sheet select,
.sheet .lede,
.sheet .muted,
.serves dd,
.day-card__list p,
.hero__note,
.fact__label,
.involve__card li,
.contact__detail,
.form__note,
.field__error,
.pull-quote figcaption,
.stat-list li,
.footer__panel p,
.footer__list {
  font-size: var(--text-body-lg);
  line-height: var(--rule-gap);
}
.numbered li { line-height: var(--leading-snug); }

/* the one exception worth keeping small: the legal line under the footer */
.footer__legal { font-size: var(--text-body-sm); line-height: var(--leading-normal); }

/* !important on the donate fine print used to force it smaller */


/* ==========================================================================
   THE PROBLEM — the caregiver's words alongside what the shelters can't do
   ========================================================================== */
.problem__grid {
  display: grid;
  grid-template-columns: .9fr 1.1fr;
  gap: var(--space-7);
  align-items: center;
}

.problem__quote { box-shadow: 3px 4px 0 var(--ink); }
.problem__quote blockquote {
  font-family: var(--font-display);
  font-size: clamp(1.15rem, 2vw, 1.5rem);
  line-height: var(--leading-snug);
  color: var(--ink);
}
.problem__quote figcaption {
  margin-top: var(--space-4);
  color: var(--ink-soft);
}

/* ==========================================================================
   NOTE BOX — a yellow gingham panel for the one line that should read as a
   statement rather than another paragraph. The check is two crossing stripe
   gradients, so there is no image to load and it never distorts.
   ========================================================================== */
.note-box {
  width: 100%;
  padding: var(--space-6) var(--space-7);

  background-color: #fef7e0;
  background-image:
    repeating-linear-gradient(90deg, transparent 0 9px, rgba(248, 213, 104, .24) 9px 18px),
    repeating-linear-gradient(0deg,  transparent 0 9px, rgba(248, 213, 104, .24) 9px 18px);
  border: none;
  border-radius: 12px;
  box-shadow: none;

  font-family: var(--font-display) !important;
  font-size: clamp(1.15rem, 2.3vw, 1.95rem) !important;
  line-height: var(--leading-snug) !important;
  color: var(--text-heading);
  text-align: center;
}

/* below this the first line can't fit on one line inside the card, so drop
   the forced break and let it wrap */
@media (max-width: 820px) {
  .note-box br { display: none; }
}

/* A <select> doesn't lay its text out like a paragraph. The ruled 30px
   line-height that every other line of body copy uses pushed the glyphs down
   inside the control and clipped their descenders. Giving it an explicit
   height with normal leading lets the browser centre the text properly. */
.field select {
  line-height: normal;
  height: 56px;
  padding-block: 0;
  padding-right: var(--space-7);   /* clear of the dropdown arrow */
}

/* ==========================================================================
   OBJECTIVE TAPE — the Objective 1/2/3 labels are strips of gingham washi
   rather than outlined pills. The check is drawn with two crossing stripe
   gradients, so the colour comes from one custom property and there is no
   image to load; the ends are torn with the same clip-path as the buttons.
   ========================================================================== */
.objective .tag {
  --gingham: 255, 140, 166;          /* pink */
  border: none;
  border-radius: 0;
  box-shadow: none;
  color: var(--tape-ink);
  font-family: var(--font-hand);
  font-weight: 700;
  font-size: var(--text-body-lg);
  letter-spacing: var(--tracking-wide);
  padding: 7px var(--space-5);
  background-color: rgba(var(--gingham), .16);
  background-image:
    repeating-linear-gradient(90deg, transparent 0 11px, rgba(var(--gingham), .42) 11px 22px),
    repeating-linear-gradient(0deg,  transparent 0 11px, rgba(var(--gingham), .42) 11px 22px);
  clip-path: polygon(
    2px 0%, calc(100% - 2px) 0%,
    calc(100% - 4px) 22%, 100% 47%,
    calc(100% - 2px) 71%, calc(100% - 4px) 100%,
    2px 100%, 4px 74%, 0px 49%, 3px 24%
  );
  filter: drop-shadow(1px 1.5px 1.5px rgba(74, 64, 50, .28));
  transform: rotate(-1.6deg);
}
.objective:nth-child(2) .tag { --gingham: 248, 213, 104; transform: rotate(1.4deg); }  /* yellow */
.objective:nth-child(3) .tag { --gingham: 123, 161,  93; }                             /* green */

/* the card clears the hero column — the earlier negative pull was riding up
   over the third numbered item */
#program { margin-top: var(--rule-gap); }

/* ==========================================================================
   THE LOGO DRAWS ITSELF
   The mark is inlined as SVG so each traced path can be stroked on with
   dashoffset, then have its colour fade in behind the line — the order runs
   roof, walls, letters left to right, then the stars.

   It only runs once the mark scrolls into view (site.js adds .is-drawing).
   Until then, and for anyone who prefers less motion or has no JS, the
   finished logo is simply shown.
   ========================================================================== */
.logo-draw { width: 100%; height: auto; display: block; }

/* resting state: the finished logo */
.logo-draw .ld-ink  { opacity: 0; }
.logo-draw .ld-fill { opacity: 1; }

/* armed, waiting to be scrolled to: nothing showing yet */
.logo-draw.is-armed .ld-fill { opacity: 0; }

.logo-draw.is-drawing .ld-ink {
  opacity: 1;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation: ld-stroke .5s linear var(--d, 0s) forwards;
}
.logo-draw.is-drawing .ld-fill {
  opacity: 0;
  animation: ld-fill .32s var(--ease-out) var(--d, 0s) forwards;
}

@keyframes ld-stroke {
  to { stroke-dashoffset: 0; }
}
@keyframes ld-fill {
  to { opacity: 1; }
}

/* the outline fades out once its colour has arrived */
.logo-draw.is-drawing .ld-ink { animation: ld-stroke .5s linear var(--d, 0s) forwards,
                                           ld-erase .3s var(--ease-out) calc(var(--d, 0s) + .5s) forwards; }
@keyframes ld-erase { to { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  .logo-draw.is-armed .ld-fill,
  .logo-draw.is-drawing .ld-fill { opacity: 1; animation: none; }
  .logo-draw .ld-ink { opacity: 0; animation: none; }
}

/* ==========================================================================
   OUR STORY PAGE
   ========================================================================== */
/* the mission sits inside a polka-dot border, like a bulletin-board frame.
   The dots are two offset radial-gradient tiles rather than an image, so the
   band stays crisp at any size and the spacing never breaks on a wide screen. */
.mission-frame {
  --dot-tile: 34px;                /* one dot per tile, offset half a tile */
  --dot-r: 6px;
  margin-top: var(--space-5);
  padding: 46px;
  background-color: var(--yellow);
  background-image:
    radial-gradient(circle var(--dot-r) at 50% 50%, #fff 97%, transparent 100%),
    radial-gradient(circle var(--dot-r) at 50% 50%, #fff 97%, transparent 100%);
  background-size: var(--dot-tile) var(--dot-tile);
  background-position: 0 0, calc(var(--dot-tile) / 2) calc(var(--dot-tile) / 2);
  border-radius: 3px;
}
.mission-frame__inner {
  background: #fff;
  padding: var(--space-6) var(--space-5);
}

/* scoped to .sheet so it outranks the `.sheet p` baseline-grid rule above —
   this is the one paragraph on the site that is not body copy */
.sheet .mission-line {
  font-family: var(--font-display);
  /* sized to land on exactly two lines. The sentence is ~45.3em wide in
     Karumbi, so each line needs ~22.7em — the ceiling is 2 x (available
     width) / 45.3, with slack for kerning. The vw term tracks the container
     until it hits its 1120px cap, where the 2.15rem ceiling takes over. */
  font-size: clamp(1.5rem, calc(4.1vw - 13px), 2.15rem);
  line-height: 1.35;
  text-wrap: balance;
  color: var(--text-heading);
  margin: 0;
}


/* --- who we serve, on three taped notes -----------------------------------
   Flat notepaper: a solid colour band across the top over a gingham check, in
   a pale tint of the same hue, with a strip of the site's washi holding it up.
   -------------------------------------------------------------------------- */
.serves {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-7);
  margin-top: var(--space-7);
}
.serves__item {
  position: relative;
  display: flex;
  flex-direction: column;
  /* the band is the title's own background, so the two can never drift apart */
  padding: 0 0 var(--space-5);
  background-color: var(--note-paper);
  background-image:
    repeating-linear-gradient(90deg, transparent 0 22px, var(--note-check) 22px 44px),
    repeating-linear-gradient(0deg,  transparent 0 22px, var(--note-check) 22px 44px);
  box-shadow: 0 2px 6px rgba(74, 64, 50, .14);
}
.serves__item--pink {
  --note-band: #ffdde7;
  --note-paper: #fff5f8;                    /* the light squares, tinted */
  --note-check: rgba(255, 140, 166, .075);
  transform: rotate(-1.6deg);
}
.serves__item--green {
  --note-band: #d8e7cd;
  --note-paper: #f4f8f0;
  --note-check: rgba(123, 161, 93, .07);
  transform: rotate(1.1deg);
}
.serves__item--yellow {
  --note-band: #fdf2cf;
  --note-paper: #fffbee;
  --note-check: rgba(248, 213, 104, .12);
  transform: rotate(-0.7deg);
}

/* --- the washi holding each note up --- */
.serves__item::before {
  content: '';
  position: absolute;
  top: -16px;
  width: 92px;
  height: 34px;
  background-size: cover;
  background-position: center;
  clip-path: polygon(
    3px 0%, calc(100% - 3px) 0%,
    calc(100% - 6px) 24%, 100% 50%,
    calc(100% - 5px) 74%, calc(100% - 3px) 100%,
    3px 100%, 5px 76%, 0px 50%, 4px 26%
  );
  filter: drop-shadow(1px 2px 2px rgba(74,64,50,.3));
  z-index: 1;
}
.serves__item--pink::before {
  left: 50%; transform: translateX(-50%) rotate(-5deg);
  background-image: url('assets/textures/tape-gingham-yellow-brand.jpg');
}
.serves__item--green::before {
  left: 28%; transform: translateX(-50%) rotate(6deg);
  background-image: url('assets/textures/tape-pink.jpg');
}
.serves__item--yellow::before {
  left: 72%; transform: translateX(-50%) rotate(-3deg);
  background-image: url('assets/textures/tape-green-gingham.jpg');
}

/* the title sits in the solid band across the top */
.serves dt {
  display: flex;
  align-items: center;
  min-height: 74px;                 /* one height whether the title wraps or not */
  margin: 0 0 var(--space-4);
  padding: var(--space-3) var(--space-5);
  background: var(--note-band);
  font-family: var(--font-display);
  font-size: var(--text-heading-lg);
  line-height: var(--leading-snug);
  color: var(--text-heading);
}
.serves dd { margin: 0; padding: 0 var(--space-5); }

/* ==========================================================================
   AN AFTERNOON — the weekly schedule (Mon / Tue / Thu)
   ========================================================================== */
.week {
  margin-top: var(--space-6);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-5);
}

.day-card {
  background: var(--paper-cream);
  border: 2.5px solid var(--border-ink);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-crayon);
  padding: var(--space-5);
}
.day-card__name {
  font-size: var(--text-heading-lg);
  padding-bottom: var(--space-3);
  margin-bottom: var(--space-4);
  border-bottom: 3px dashed var(--green);
}

.day-card__list { display: grid; gap: var(--space-4); }
.day-card__list li {
  display: grid;
  gap: var(--space-1);
  background: var(--surface-card);
  border: 2px solid var(--ink);
  border-radius: var(--radius-sm);
  box-shadow: var(--shadow-crayon-sm);
  padding: var(--space-3) var(--space-4);
}
.day-card__list strong {
  font-family: var(--font-display);
  font-size: var(--text-heading-md);
  font-weight: 400;
  color: var(--text-heading);
  line-height: var(--leading-tight);
}
.day-card__list p { font-size: var(--text-body-sm); margin-top: var(--space-1); }

.slot__time {
  font-family: var(--font-hand);
  font-weight: 700;
  font-size: var(--text-body-sm);
  color: var(--ink);
}
/* --- the session tapes ---------------------------------------------------
   The real washi rolls from the design system's texture set, not drawn ones:
   pink and yellow polka dot, yellow and green gingham — the two yellows recoloured
   from the same rolls to HAVEN yellow. Session A and B swap
   patterns from one day to the next, and each day gets its own pairing. The
   torn edge is a clip-path, which is why the shadow is a drop-shadow — a
   box-shadow would trace the untorn rectangle instead.
   ------------------------------------------------------------------------ */
.slot__label {
  justify-self: start;
  font-family: var(--font-hand);
  font-weight: 700;
  font-size: var(--text-body-sm);
  letter-spacing: var(--tracking-wide);
  color: var(--tape-ink);
  padding: 4px var(--space-4);
  margin-bottom: var(--space-2);
  background-size: cover;
  background-position: center;
  clip-path: polygon(
    2px 0%, calc(100% - 2px) 0%,
    calc(100% - 4px) 22%, 100% 47%,
    calc(100% - 2px) 71%, calc(100% - 4px) 100%,
    2px 100%, 4px 74%, 0px 49%, 3px 24%
  );
  filter: drop-shadow(1px 1.5px 1.5px rgba(74, 64, 50, .28));
  transform: rotate(-1.8deg);
}

.tape--dots-pink     { background-image: url('assets/textures/tape-pink.jpg'); }
.tape--dots-yellow   { background-image: url('assets/textures/tape-dots-yellow-brand.jpg'); }
.tape--gingham-yellow{ background-image: url('assets/textures/tape-gingham-yellow-brand.jpg'); }
.tape--gingham-green { background-image: url('assets/textures/tape-green-gingham.jpg'); }
.tape--gingham-pink  { background-image: url('assets/textures/tape-gingham-pink-brand.jpg'); }

/* every scrap leans a little differently, the way torn tape would */
.week .day-card:nth-child(1) li:nth-child(3) .slot__label,
.week .day-card:nth-child(3) li:nth-child(1) .slot__label { transform: rotate(1.5deg); }
.week .day-card:nth-child(2) li:nth-child(1) .slot__label { transform: rotate(1.2deg); }
.week .day-card:nth-child(2) li:nth-child(3) .slot__label { transform: rotate(-1.4deg); }
.week .day-card:nth-child(1) li:nth-child(3) .slot__label { --tape: var(--green); }
.week .day-card:nth-child(2) li:nth-child(1) .slot__label { --tape: var(--yellow); }
.week .day-card:nth-child(2) li:nth-child(3) .slot__label { --tape: var(--green); }
.week .day-card:nth-child(3) li:nth-child(1) .slot__label { --tape: var(--yellow); }
.week .day-card:nth-child(3) li:nth-child(3) .slot__label { --tape: var(--pink); }

/* the two short, unglamorous slots stay visually quiet */
.day-card__list .slot--transition,
.day-card__list .slot--pickup {
  grid-template-columns: auto 1fr;
  align-items: baseline;
  gap: var(--space-3);
  background: transparent;
  border: none;
  border-left: 3px dashed var(--border-soft);
  border-radius: 0;
  box-shadow: none;
  padding: var(--space-1) var(--space-4);
}
.day-card__list .slot--transition strong,
.day-card__list .slot--pickup strong {
  font-family: var(--font-hand);
  font-size: var(--text-body-sm);
  color: var(--ink-soft);
  font-weight: 400;
}


/* ==========================================================================
   THE COMIC STRIP — the founding story, four panels
   The frames and the drawings are real vector outlines, so they can be drawn
   on stroke by stroke: every path is dashed to its own length, then the dash
   offset is animated to zero, and the fill fades in behind it as it lands.
   Panel shapes are percentage-only so the SVG frame and the clip-path agree
   whatever height the panels end up.
   ========================================================================== */
.comic {
  display: grid;
  grid-template-columns: repeat(20, 1fr);
  row-gap: 0;
  margin-top: var(--space-3);
  counter-reset: panel;
}

.comic__panel { position: relative; }
.comic__inner {
  position: relative;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--space-4);
  background: #fff;
  overflow: hidden;
}

/* the frame is the drawn outline, not a CSS border */
.panel-frame {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 3;
  pointer-events: none;
}
.panel-frame__line { fill: none; stroke: #1a1a18; stroke-width: 4.5; }

.comic__panel:nth-child(1) { --i: 0; grid-column: 1 / 12; grid-row: 1; min-height: 310px;
  clip-path: polygon(0 0, 98% 0, 64.1% 89.7%, 0 84.5%); }
.comic__panel:nth-child(1) .comic__inner {
  clip-path: polygon(0 0, 98% 0, 64.1% 89.7%, 0 84.5%);
  justify-content: flex-start;
  padding: 6% 40% 18% var(--space-5);
}

.comic__panel:nth-child(2) { --i: 1; grid-column: 7 / 21; grid-row: 1; min-height: 310px;
  clip-path: polygon(35.9% 0, 100% 0, 100% 98.7%, 9.2% 89.7%); }
.comic__panel:nth-child(2) .comic__inner {
  clip-path: polygon(35.9% 0, 100% 0, 100% 98.7%, 9.2% 89.7%);
  padding: 7% var(--space-4) 10% 34%;
}

.comic__panel:nth-child(3) { --i: 2; grid-column: 1 / 11; grid-row: 2;
  margin-top: -40px; min-height: 300px;
  clip-path: polygon(0 0, 100% 7.3%, 100% 100%, 0 100%); }
.comic__panel:nth-child(3) .comic__inner {
  clip-path: polygon(0 0, 100% 7.3%, 100% 100%, 0 100%);
  padding: 34px var(--space-5) var(--space-5);
}

.comic__panel:nth-child(4) { --i: 3; grid-column: 11 / 21; grid-row: 2;
  margin-left: 8px; margin-top: -18px; min-height: 300px;
  clip-path: polygon(0 0, 100% 7.3%, 100% 100%, 0 100%); }
.comic__panel:nth-child(4) .comic__inner {
  clip-path: polygon(0 0, 100% 7.3%, 100% 100%, 0 100%);
  padding: 36px var(--space-5) var(--space-5);
}

/* --- the drawings, as strokes -------------------------------------------- */
.ink { position: relative; z-index: 1; width: 100%; max-width: 205px; height: auto;
       align-self: center; display: block; }
.comic__panel:nth-child(1) .ink { max-width: 245px; }
.comic__panel:nth-child(4) .ink { max-width: 168px; }
.ink__s { fill: #1a1a18; }

/* every line of narration sits in its own box, the way a strip captions a panel */
.comic__caption,
.comic__inner p {
  position: relative;
  z-index: 1;
  margin: 0;
  background: var(--paper-cream);
  border: 2.5px solid #1a1a18;
  padding: 3px var(--space-3);
  font-family: var(--font-display);   /* Karumbi */
  font-size: var(--text-heading-md);
  color: var(--text-heading);
  line-height: 1.12;
}
.comic__caption {
  align-self: flex-start;
  margin-left: 44px;          /* clears the panel number */
}

/* --- drawn on, stroke by stroke -----------------------------------------
   Held back only when site.js can drive it, so without JS the strip is
   simply finished and there.
   ------------------------------------------------------------------------ */
.comic.is-armed .ink__s { opacity: 0; }

/* the frames are simply there — only the drawings are drawn on.
   Each mark: outline first, fill arriving behind it as it lands. */
.comic.is-drawing .ink__s {
  fill: none;
  stroke: #1a1a18;
  stroke-width: 3;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  animation:
    draw-line .28s linear calc(var(--i) * .62s + var(--d, 0s)) forwards,
    draw-fill .2s ease-out calc(var(--i) * .62s + .18s + var(--d, 0s)) forwards;
}

@keyframes draw-line { to { stroke-dashoffset: 0; } }
@keyframes draw-fill { to { fill: #1a1a18; stroke-width: 0; } }

/* the panel number, in the corner like a strip */
.comic__panel:nth-child(1) .comic__inner::before { top: 0; }
.comic__panel:nth-child(2) .comic__inner::before { left: auto; right: 0; }
.comic__inner::before {
  counter-increment: panel;
  content: counter(panel);
  position: absolute;
  top: 0;
  left: 0;
  width: 42px;
  height: 36px;
  display: grid;
  place-items: center;
  z-index: 2;
  font-family: var(--font-display);
  font-size: var(--text-heading-md);
  color: #fff;
  background: #1a1a18;
}

/* someone who prefers less motion just gets the finished strip */
@media (prefers-reduced-motion: reduce) {
  .comic.is-armed .ink__s { opacity: 1; }
  .comic.is-drawing .ink__s { animation: none; }
  .comic.is-drawing .ink__s { fill: #1a1a18; stroke: none; }
}

/* Our Journey follows straight on from the profile cards */
#about { margin-top: var(--rule-gap); }
/* a small lift under the mission frame on the our story page */
#needs { margin-top: calc(var(--rule-gap) * 2 - 12px); }
/* the Chronicle follows close on the group photo */
#news { margin-top: var(--rule-gap); }

/* the three of them, closing out the founding story */
.team-photo {
  position: relative;
  margin: var(--space-6) 0 0;
}
/* the photo reads as the strip's last panel, so it carries the next number */
.team-photo::before {
  content: '5';
  position: absolute;
  top: 4px;
  left: 4px;
  width: 42px;
  height: 36px;
  display: grid;
  place-items: center;
  z-index: 2;
  font-family: var(--font-display);
  font-size: var(--text-heading-md);
  color: #fff;
  background: #1a1a18;
}
.team-photo img {
  display: block;
  width: 100%;
  height: auto;
  border: 4px solid #1a1a18;
  border-radius: 2px;
  box-shadow: var(--shadow-crayon);
}
/* a last narration box, laid over the photo like the ones in the strip —
   centred along the bottom, closing the scene */
.team-photo__caption {
  position: absolute;
  bottom: var(--space-5);
  left: 50%;
  transform: translateX(-50%);
  max-width: 84%;
  white-space: nowrap;
  background: var(--paper-cream);
  border: 3px solid #1a1a18;
  padding: 4px var(--space-5);
  font-family: var(--font-display);
  font-size: var(--text-display-md);
  color: var(--text-heading);
  line-height: 1.12;
}

/* ==========================================================================
   ABOUT — the press, laid out as a newspaper front page
   Set in Gaegu like the rest of the site, in the HAVEN palette only — the
   newspaper reads as a newspaper from the hairline rules, the column gutters
   and the masthead, not from a borrowed serif. Gaegu runs small, so every
   size here is a step up from where the serif sat.
   ========================================================================== */
.newsprint {
  --np-rule: var(--border-soft);
  margin-top: var(--space-6);
  background: var(--paper);
  border: 2.5px solid var(--ink);
  box-shadow: var(--shadow-crayon);
  padding: var(--space-5) var(--space-6) var(--space-6);
  font-family: var(--font-body);
  color: var(--ink);
}

/* --- masthead --- */
.newsprint__masthead {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--space-4);
  padding-bottom: var(--space-4);
}
.newsprint .newsprint__date,
.newsprint .newsprint__ears {
  margin: 0;
  font-size: 1rem;
  line-height: 1.5;
  color: var(--ink-soft);
}
.newsprint .newsprint__ears {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 4px;
}
/* the HAVEN mark, sitting in the masthead ear */
.newsprint__logo { width: 62px; height: auto; }
.newsprint .newsprint__date #npEdition { text-decoration: underline; }
.newsprint__name {
  margin: 0;
  text-align: center;
  font-weight: 700;
  font-size: clamp(2.2rem, 5vw, 3.6rem);
  line-height: 1;
  letter-spacing: .01em;
  color: var(--denim);
}
.newsprint .newsprint__founded {
  margin: 4px 0 0;
  text-align: center;
  font-size: .8rem;
  letter-spacing: .06em;
  color: var(--ink-soft);
}

/* --- section bar --- */
.newsprint__nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-5);
  padding: 6px 0;
  border-top: 1px solid var(--ink);
  border-bottom: 1px solid var(--ink);
  font-size: .9rem;
  letter-spacing: .03em;
  color: var(--ink);
}
/* thin dividers between the sections, the way a section bar is ruled */
.newsprint__nav > * + *::before {
  content: '';
  display: inline-block;
  width: 1px;
  height: .85em;
  margin-right: var(--space-5);
  vertical-align: -1px;
  background: var(--np-rule);
}
.newsprint__nav a { font-weight: 700; }

/* --- the page: rail | lead | rail --- */
.newsprint__page {
  display: grid;
  grid-template-columns: 1fr 1.75fr 1fr;
  gap: 0;
  margin-top: var(--space-5);
}
.newsprint__rail { padding-right: var(--space-5); }
.newsprint__rail--right { padding: 0 0 0 var(--space-5); border-left: 1px solid var(--np-rule); }
.newsprint__lead {
  padding: 0 var(--space-5);
  border-left: 1px solid var(--np-rule);
}

.newsprint .newsprint__railhead {
  margin: 0 0 var(--space-3);
  padding-bottom: 4px;
  border-bottom: 2px solid var(--ink);
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--denim);
}

/* --- rail stories --- */
.newsprint__item + .newsprint__item {
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--np-rule);
}
.newsprint__item h4 {
  margin: 0 0 4px;
  font-size: 1.2rem;
  font-weight: 700;
  line-height: 1.2;
}
.newsprint .newsprint__kicker {
  margin: 0 0 4px;
  font-size: .8rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--green-deep);
}
.newsprint .newsprint__kicker--red { color: var(--denim); }
.newsprint .newsprint__byline {
  margin: 0;
  font-size: .8rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.newsprint .newsprint__dek {
  margin: var(--space-2) 0 0;
  font-size: 1rem;
  line-height: 1.45;
}

/* --- the lead --- */
.newsprint__lead img {
  width: 100%;
  height: auto;
  display: block;
  margin-bottom: var(--space-3);
}
/* the cutline under the lead photo */
.newsprint .newsprint__caption {
  margin: 0 0 var(--space-3);
  font-size: .8rem;
  line-height: 1.4;
  font-style: italic;
  color: var(--ink-soft);
  padding-bottom: var(--space-3);
  border-bottom: 1px solid var(--np-rule);
}

.newsprint__leadhead {
  margin: 0 0 6px;
  text-align: center;
  font-size: clamp(1.5rem, 2.8vw, 2.15rem);
  font-weight: 700;
  line-height: 1.14;
}
.newsprint__lead .newsprint__byline { text-align: center; }
.newsprint .newsprint__leaddek {
  margin: var(--space-3) 0 0;
  font-size: 1.06rem;
  line-height: 1.5;
  text-align: center;
}
/* the two pull-quotes under the lead, stacked — Chang, then Leohansson */
.newsprint__split {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--np-rule);
}
.newsprint__split p {
  margin: 0;
  font-size: 1rem;
  line-height: 1.45;
  font-style: italic;
}
.newsprint__split p + p { border-top: 1px solid var(--np-rule); padding-top: var(--space-4); }

/* thumbnails in the left rail */
.newsprint__thumb {
  width: 100%;
  height: auto;
  display: block;
  margin-bottom: var(--space-3);
}

/* the picture block that closes the right rail — one column, stacked */
.newsprint__aside {
  margin: var(--space-5) 0 0;
  padding-top: var(--space-4);
  border-top: 2px solid var(--ink);
}
.newsprint__aside figure { margin: 0 0 var(--space-4); }
.newsprint__aside figure:last-child { margin-bottom: 0; }
.newsprint__aside img { width: 100%; height: auto; display: block; }
.newsprint__aside figcaption {
  margin-top: var(--space-2);
  font-size: .84rem;
  line-height: 1.35;
  font-style: italic;
  color: var(--ink-soft);
}

/* --- most read --- */
.newsprint__most { margin: 0; padding: 0; list-style: none; counter-reset: mr; }
.newsprint__most li {
  counter-increment: mr;
  display: grid;
  grid-template-columns: 26px 1fr;
  gap: var(--space-2);
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--np-rule);
  font-size: 1rem;
  line-height: 1.25;
}
.newsprint__most li::before {
  content: counter(mr);
  grid-row: span 2;
  width: 24px; height: 24px;
  display: grid; place-items: center;
  border: 1.5px solid var(--denim);
  border-radius: 50%;
  font-size: 1rem;
  color: var(--denim);
}
.newsprint__most span {
  grid-column: 2;
  font-size: .78rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.newsprint a { text-decoration: none; color: inherit; }
.newsprint a:hover { color: var(--denim); text-decoration: underline; text-underline-offset: 3px; }

/* ==========================================================================
   PARTNERS — a nine-piece jigsaw, one partner per piece
   Drawn as a single inline SVG. Every corner and every edge is generated once
   with a little jitter and then shared by both neighbouring pieces, so the
   board still interlocks exactly while no line is quite straight. Labels are
   pre-wrapped to the measured Gaegu width of each piece.
   ========================================================================== */
.puzzle {
  display: block;
  width: min(100%, 620px);
  height: auto;
  margin: var(--space-6) auto 0;
}
.pz-name {
  font-family: var(--font-body);   /* Gaegu */
  font-weight: 700;
  font-size: 11.5px;
  fill: var(--ink);
  text-anchor: middle;
}
.pz-sub {
  font-family: var(--font-body);   /* Gaegu */
  font-size: 8px;
  fill: var(--ink);
  text-anchor: middle;
}
/* every piece carries its own wobbling outline, so no separate frame is needed */
.pz-piece {
  stroke: var(--ink);
  stroke-width: 1.9;
  stroke-linejoin: round;
  stroke-linecap: round;
}

/* --- the board assembles itself ------------------------------------------
   Each piece flies in from beyond its own corner and settles into place,
   corners first and the centre last. Only armed when site.js can drive it,
   so without JS the board is simply finished.
   ------------------------------------------------------------------------ */
.pz-cell { transform-box: fill-box; transform-origin: center; }

.puzzle.is-armed .pz-cell { opacity: 0; }

.puzzle.is-solving .pz-cell {
  animation: pz-drop .62s cubic-bezier(.22,.9,.3,1.08) calc(var(--i) * .11s) both;
}

@keyframes pz-drop {
  from { opacity: 0; transform: translate(var(--tx), var(--ty)) rotate(var(--rot)) scale(.94); }
  60%  { opacity: 1; }
  to   { opacity: 1; transform: translate(0, 0) rotate(0deg) scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .puzzle.is-armed .pz-cell { opacity: 1; }
  .puzzle.is-solving .pz-cell { animation: none; }
}

/* ==========================================================================
   RESPONSIVE
   ========================================================================== */
@media (max-width: 960px) {
  .hero__grid,
  .listen__grid,
  .contact__grid { grid-template-columns: 1fr; }
  .pillars, .involve, .team, .week, .serves { grid-template-columns: 1fr; }
  /* a broadsheet does not fit on a phone — stack the rails under the lead */
  .newsprint__page { grid-template-columns: 1fr; }
  .newsprint__lead { order: -1; padding: 0 0 var(--space-5); border-left: none; }
  .newsprint__rail,
  .newsprint__rail--right {
    padding: var(--space-5) 0 0;
    border-left: none;
    border-top: 1px solid var(--np-rule);
  }
  .newsprint__masthead { grid-template-columns: 1fr; text-align: center; }
  .newsprint__ears, .newsprint__date { text-align: center; }
  /* the diagonals crowd the text at this width — square the panels off */
  .comic { grid-template-columns: 1fr; row-gap: var(--space-4); }
  .comic__panel:nth-child(1),
  .comic__panel:nth-child(2),
  .comic__panel:nth-child(3),
  .comic__panel:nth-child(4) {
    grid-column: auto; grid-row: auto;
    clip-path: none; min-height: 0; margin-top: 0; margin-left: 0;
  }
  .comic__panel:nth-child(1) .comic__inner,
  .comic__panel:nth-child(2) .comic__inner,
  .comic__panel:nth-child(3) .comic__inner,
  .comic__panel:nth-child(4) .comic__inner {
    clip-path: none;
    padding: var(--space-6) var(--space-5) var(--space-5);
  }
  .panel-frame__line { display: none; }
  .comic__panel { border: 4px solid #1a1a18; }
  .problem__grid { grid-template-columns: 1fr; }
  .pull-quote { position: static; }
  .day-card.tilt-2, .reveal.day-card.tilt-2.is-in { transform: none; }
  /* the notes sit straight when they stack */
  .serves__item--pink, .serves__item--green, .serves__item--yellow { transform: none; }
  .footer__panel { grid-template-columns: 1fr; }
  .hero__art { order: -1; }
  .hero__art-mini { display: none; }

  .nav__toggle { display: block; }
  .nav__lockup { height: 34px; }
  .nav__links {
    display: none;
    position: absolute;
    top: calc(100% + 10px);
    right: var(--space-5);
    left: var(--space-5);
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-4);
    background: var(--paper);
    border: 2.5px solid var(--ink);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-crayon);
    padding: var(--space-5);
  }
  .nav__links.is-open { display: flex; }
  .nav__link { border-bottom: 2.5px dashed var(--border-soft); padding-bottom: var(--space-2); }
}

@media (max-width: 720px) {
  /* narrower page: pull the margin rule in and lose the stitching */
  .sheet {
    --sheet-margin: 34px;
    --rule-gap: 28px;
    padding: var(--space-6) var(--space-4) var(--space-6) calc(var(--sheet-margin) + var(--space-3));
  }
  .sheet::after { display: none; }
  .book__scene { width: min(300px, 72vw); }
}

@media (max-width: 560px) {

  .form__row { grid-template-columns: 1fr; }
  .stat-list li { grid-template-columns: 1fr; gap: var(--space-2); }
  .day-card { padding: var(--space-4); }
  .card { padding: var(--space-4); }
  .card--lg { padding: var(--space-5); }
  .team-photo__caption {
    white-space: normal;
    font-size: var(--text-heading-md);
    padding: 3px var(--space-3);
    text-align: center;
  }
  .sheet .mission-line { font-size: clamp(1.6rem, 5vw, 2.2rem); }
  .mission-frame { padding: 26px; --dot-tile: 26px; --dot-r: 4.5px; }
  .mission-frame__inner { padding: var(--space-5); }
}
