/* ============================================================
   Noah's Story Charity - shared primitives
   Every rule is .ns- scoped. No element-level rules, no importance overrides.
   Values are lifted verbatim from the approved homepage.
   ============================================================ */

/* ---------------- Layout ---------------- */
.ns-wrap {
  max-width: 1280px;
  margin-inline: auto;
  padding-inline: clamp(18px, 4vw, 40px);
}
.ns-wrap--narrow { max-width: 920px; }

/* ---------------- Typography ---------------- */
.ns-eyebrow {
  margin: 0;
  font-family: var(--ns-display);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: .19em;
  text-transform: uppercase;
  color: var(--ns-link);
}
.ns-eyebrow--sage { color: var(--ns-green-deep); }
.ns-eyebrow--hero {
  font-size: clamp(11px, 1.1vw, 13px);
  letter-spacing: .17em;
  color: var(--ns-blue-mid);
}

.ns-h1 {
  margin: 0;
  font-family: var(--ns-display);
  font-weight: 700;
  font-size: clamp(34px, 4.6vw, 60px);
  line-height: 1.12;
  letter-spacing: -.015em;
  color: var(--ns-navy);
  text-wrap: pretty;
}
.ns-h2 {
  margin: 0;
  font-family: var(--ns-display);
  font-weight: 700;
  font-size: clamp(27px, 3.3vw, 42px);
  line-height: 1.2;
  color: var(--ns-navy);
  text-wrap: pretty;
}
.ns-h3 {
  margin: 0;
  font-family: var(--ns-display);
  font-weight: 700;
  font-size: 19.5px;
  line-height: 1.35;
  color: var(--ns-navy);
}

.ns-lead {
  margin: 0;
  font-family: var(--ns-body-font);
  font-size: clamp(16px, 1.15vw, 18px);
  line-height: 1.75;
  color: var(--ns-body);
}
.ns-body {
  margin: 0;
  font-family: var(--ns-body-font);
  font-size: 15px;
  line-height: 1.68;
  color: var(--ns-body);
}

/* ---------------- Buttons ---------------- */
.ns-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  font-family: var(--ns-display);
  font-weight: 700;
  font-size: 12.5px;
  letter-spacing: .11em;
  text-transform: uppercase;
  text-align: center;
  text-decoration: none;
  padding: 16px 26px;
  min-height: 50px;
  border: 0;
  border-radius: var(--ns-r-pill);
  background: none;
  color: inherit;
  cursor: pointer;
  transition: background-color .25s ease, border-color .25s ease,
              color .25s ease, transform .25s ease,
              gap .25s ease, padding .25s ease;
}
.ns-btn svg { flex: none; }
/* CTA icons: small directional movement - the arrow gap widens on hover */
.ns-btn:hover { text-decoration: none; gap: 15px; }

/* Size variants from the approved design */
.ns-btn--lg { font-size: 13.5px; padding: 17px 30px; min-height: 52px; } /* hero CTA */
.ns-btn--sm { font-size: 12px; gap: 9px; padding: 12px 20px; min-height: 44px; } /* card EXPLORE */

/* Colour variants */
.ns-btn--sage { background: var(--ns-green-btn); color: var(--ns-white); }
.ns-btn--sage:hover {
  background: var(--ns-green-btn-hover);
  color: var(--ns-white);
  transform: translateY(-2px);
}
.ns-btn--blue { background: var(--ns-blue-btn); color: var(--ns-white); }
.ns-btn--blue:hover {
  background: var(--ns-blue-btn-hover);
  color: var(--ns-white);
  transform: translateY(-2px);
}
.ns-btn--outline {
  background: var(--ns-white);
  color: var(--ns-link);
  border: 1.6px solid var(--ns-blue-soft);
  padding: 15px 26px;
}
.ns-btn--outline:hover {
  background: var(--ns-blue-pale);
  border-color: var(--ns-blue);
  color: var(--ns-link);
  transform: none;
}
.ns-btn--outline-sage {
  background: var(--ns-white);
  color: var(--ns-green-deep);
  border: 1.6px solid var(--ns-sage-soft);
  padding: 15px 26px;
}
.ns-btn--outline-sage:hover {
  background: var(--ns-sage-pale);
  border-color: var(--ns-sage);
  color: var(--ns-green-deep);
  transform: none;
}
.ns-btn--link {
  background: none;
  color: var(--ns-link);
  border-radius: 0;
  border-bottom: 1.6px solid var(--ns-blue-soft);
  padding: 8px 2px;
  min-height: 44px;
}
.ns-btn--link:hover {
  background: none;
  border-color: var(--ns-link);
  color: var(--ns-link);
  transform: none;
}
/* Card EXPLORE hover: gap widens and trailing padding tucks in.
   Declared after the colour variants so it wins at equal specificity. */
.ns-btn--sm:hover { gap: 15px; padding-right: 17px; transform: none; }

/* ---------------- Cards + panels ---------------- */
.ns-card {
  background: var(--ns-white);
  border: 1px solid var(--ns-border-card);
  border-radius: var(--ns-r-card);
  overflow: hidden;
  transition: transform .32s ease, box-shadow .32s ease;
}
.ns-card:hover {
  transform: translateY(-5px);
  box-shadow: var(--ns-shadow-card);
}
.ns-card__body { padding: 22px 22px 24px; }

.ns-panel {
  background: var(--ns-cream);
  border-radius: var(--ns-r-panel-fluid);
  padding: clamp(28px, 3.4vw, 50px) clamp(22px, 3vw, 44px);
}
.ns-panel--blue { background: var(--ns-blue-pale); }
.ns-panel--sage { background: var(--ns-sage-pale); }

/* ---------------- Tinted fields (full-width section backgrounds) ---------------- */
.ns-field--blue { background: var(--ns-blue-pale); }
.ns-field--sage { background: var(--ns-sage); }
.ns-field--cream { background: var(--ns-cream); }

/* ---------------- Organic blob image mask ---------------- */
.ns-blob {
  border-radius: var(--ns-blob-1);
  overflow: hidden;
  aspect-ratio: 1 / .94;
  box-shadow: var(--ns-shadow-blob);
}
.ns-blob--2 {
  border-radius: var(--ns-blob-2);
  aspect-ratio: 5 / 4;
  box-shadow: var(--ns-shadow-blob-2);
}
.ns-blob--3 {
  border-radius: var(--ns-blob-3);
  aspect-ratio: 5 / 4;
}
.ns-blob--flat { box-shadow: none; }
.ns-blob img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ---------------- "Photography to be supplied" placeholder ---------------- */
.ns-placeholder {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  overflow: hidden;
  background: var(--ns-ph-grad-blue);
  font-family: var(--ns-display);
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ns-body);
}
.ns-placeholder--sage {
  background: var(--ns-ph-grad-sage);
  color: var(--ns-green-ink-3);
}
/* An image slot with no photograph yet.
   It used to announce "PHOTOGRAPHY TO BE SUPPLIED", which read as an unfinished
   page to every visitor and was spoken aloud to screen-reader users. It now
   renders the brand's infinity motif on the same soft field: a deliberate,
   quiet surface that looks intended. The image field stays live, so dropping a
   photograph into it in the builder replaces this with no other change. */
.ns-placeholder__motif {
  width: clamp(52px, 26%, 104px);
  height: auto;
  opacity: .42;
  color: var(--ns-blue-mid);
}

.ns-placeholder--sage .ns-placeholder__motif {
  color: var(--ns-green-deep);
  opacity: .38;
}

/* ---------------- Motifs (inline SVG hearts / infinity lines / stars) ---------------- */
.ns-motif { display: block; pointer-events: none; }
.ns-motif--float { animation: nsFloat 7s ease-in-out infinite; }
.ns-motif--twinkle { animation: nsTwinkle 5s ease-in-out infinite; }
/* Apply to an SVG path; set --ns-len to the measured path length where known */
.ns-draw {
  stroke-dasharray: var(--ns-len, 600);
  stroke-dashoffset: var(--ns-len, 600);
  animation: nsDraw 1.6s var(--ns-ease-draw) forwards;
}

@keyframes nsFloat {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-5px); }
}
@keyframes nsTwinkle {
  0%, 100% { opacity: .35; }
  50% { opacity: 1; }
}
@keyframes nsDraw {
  from { stroke-dashoffset: var(--ns-len, 600); }
  to { stroke-dashoffset: 0; }
}

/* ---------------- Soft SVG wave dividers ---------------- */
.ns-wave { display: block; width: 100%; height: clamp(44px, 5.5vw, 88px); }
.ns-wave--short { height: clamp(40px, 5vw, 80px); }
.ns-wave--tall { height: clamp(48px, 6vw, 104px); }
.ns-wave--flip { transform: scaleY(-1); }

/* ---------------- Focus visibility (WCAG) ---------------- */
[class^="ns-"]:focus-visible,
[class*=" ns-"]:focus-visible {
  outline: 3px solid var(--ns-link);
  outline-offset: 3px;
}

/* ---------------- Reduced motion: kill all animation and transition ----------------
   [class][...] doubles specificity so these outrank every single-class rule
   above through the cascade alone. */
@media (prefers-reduced-motion: reduce) {
  [class^="ns-"][class],
  [class*=" ns-"][class],
  [class^="ns-"][class]::before,
  [class*=" ns-"][class]::before,
  [class^="ns-"][class]::after,
  [class*=" ns-"][class]::after {
    animation: none;
    transition: none;
  }
  /* Draw paths must render fully, not sit hidden at full dash offset */
  .ns-draw[class] {
    stroke-dasharray: none;
    stroke-dashoffset: 0;
  }
  /* No hover lifts either - a snap without transition is jarring */
  .ns-btn[class]:hover,
  .ns-card[class]:hover {
    transform: none;
  }
}

/* ============================================================
   Justified body copy (client request, September 2026).

   Applied ONLY to long-form prose: the paragraphs and list items inside
   rich content, legal content, the feature-split body, FAQ answers, the
   status note and the form panel's supporting column.

   Deliberately NOT applied to headings, buttons, menu items, eyebrows,
   short labels, breadcrumbs, form labels, card titles, card bodies,
   quotes, leads or captions - justification needs a long measure to look
   right, and forcing it on short text is what produces the stretched,
   gappy lines the client is trying to avoid.

   `hyphens: auto` is on with justification because without it English
   justified text opens rivers of white space between words. Below 640px
   the measure is too narrow for justification to help at all, so it is
   turned off along with hyphenation.
   ============================================================ */
.ns-rich-content__body > p,
.ns-rich-content__body > ul > li,
.ns-rich-content__body > ol > li,
.ns-legal-content__body > p,
.ns-legal-content__body > ul > li,
.ns-legal-content__body > ol > li,
.ns-feature-split__body > p,
.ns-faq__answer > p,
.ns-status-note__body > p,
.ns-form-panel__aside-body > p {
  text-align: justify;
  text-justify: inter-word;
  -webkit-hyphens: auto;
  hyphens: auto;
  hyphenate-limit-chars: 8 4 4;
}

/* A blockquote inside rich content stays ragged-right: it is a person
   speaking, and justifying a quotation reads as typeset, not spoken. */
.ns-rich-content__body blockquote p {
  text-align: left;
  -webkit-hyphens: manual;
  hyphens: manual;
}

@media (max-width: 640px) {
  .ns-rich-content__body > p,
  .ns-rich-content__body > ul > li,
  .ns-rich-content__body > ol > li,
  .ns-legal-content__body > p,
  .ns-legal-content__body > ul > li,
  .ns-legal-content__body > ol > li,
  .ns-feature-split__body > p,
  .ns-faq__answer > p,
  .ns-status-note__body > p,
  .ns-form-panel__aside-body > p {
    text-align: left;
    -webkit-hyphens: manual;
    hyphens: manual;
  }
}


/* ------------------------------------------------------------------
   Illustrations stand on their own.

   Every image frame on this site is an organic "blob": a tinted field with a
   soft radius, a drop shadow and a fixed aspect ratio. That is right for a
   PHOTOGRAPH, which needs a shape to sit in. It is wrong for the line
   illustrations, which already carry their own composition.

   Targeted at the image's DIRECT PARENT rather than a list of frame class
   names. Enumerating the classes missed `.ns-rich-content__frame`, which left
   the candle in a white disc and cropped its holder off with object-fit:cover.
   `*:has(> img)` cannot over-match: it selects only the element the image
   actually sits in.

   Scoped to `.ns-main` so the header and footer logos - which live outside it -
   keep their own sizing.

   `aspect-ratio: auto` matters as much as the rest: the frame's 4/3 box would
   otherwise letterbox a tall drawing down to almost nothing. An SVG with a
   viewBox carries its own intrinsic ratio, so nothing shifts on load.
   ------------------------------------------------------------------ */
.ns-main *:has(> img[src$=".svg"]),
.ns-main *:has(> img[src*="noahs-story-logo"]) {
  background: none !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  aspect-ratio: auto !important;
  padding: 0;
}

.ns-main img[src$=".svg"],
.ns-main img[src*="noahs-story-logo"] {
  object-fit: contain !important;
  border-radius: 0 !important;
  background: none;
  width: 100%;
  height: auto;
}

/* A rich-content block with NO picture should be text, not text beside an empty
   decorative disc. The ornament exists to balance a two-column row; with nothing
   in the other column it reads as a slot someone forgot to fill. */
.ns-rich-content__grid:not(:has(.ns-rich-content__figure)) .ns-rich-content__ornament {
  display: none;
}

.ns-rich-content__grid:not(:has(.ns-rich-content__figure)) {
  display: block;
}

.ns-rich-content__grid:not(:has(.ns-rich-content__figure)) .ns-rich-content__body {
  max-width: 72ch;
}
