/* ==========================================================================
   Sanctuary Insurance v2, HOME page-scoped layer (2026-07-11 revamp).
   Catalog components re-tokened to design/brands/sanctuary.md; the shared
   Phantom clone system stays in styles.css untouched.
   Placements: 003 Typewriter, 013 Icon Slide In Button, 016 AnimatedNumber,
   011 Tilt Card (JS-only, no CSS needed beyond will-change), 019 Logo
   Preloader, 020 Interactive Gradient (CSS variant), 027 Progress Bar,
   091 Dragable Ticker.
   House rule: no em or en dashes anywhere in this file.
   ========================================================================== */

/* --------------------------------------------------------------------------
   019 Logo Preloader: Sanctuary mark splash, once per session (html.preloading
   set by the head gate script), ~1.2s total, unmounts clean via home.js.
   -------------------------------------------------------------------------- */
.preloader { display: none; }
html.preloading .preloader {
  display: flex;
  position: fixed;
  inset: 0;
  z-index: 1000;                      /* above the nav (100) and the progress line (200) */
  align-items: center;
  justify-content: center;
  background: var(--world-light);     /* kit: blush canvas */
  transition: opacity .7s cubic-bezier(.7, .2, .2, 1); /* catalog 019 preloader-smooth, exact */
}
html.preloading .preloader img {
  width: 220px;
  height: auto;
  transform: translateY(80px);        /* catalog 019 init state, exact */
  opacity: 0;
  transition: transform .7s cubic-bezier(.7, .2, .2, 1), opacity .7s cubic-bezier(.7, .2, .2, 1);
  will-change: transform, opacity;
}
html.preloading .preloader.pre-in img { transform: translateY(0); opacity: 1; }
html.preloading .preloader.pre-out img { transform: translateY(-80px); opacity: 0; }
html.preloading .preloader.pre-out { opacity: 0; }

/* --------------------------------------------------------------------------
   027 Progress Bar: thin scroll progress line, kit accent, top of viewport.
   Fill is scaleX so the spring rides the compositor only.
   -------------------------------------------------------------------------- */
.scroll-progress {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 3px;
  z-index: 200;                       /* above the floating nav pill */
  background: transparent;            /* flat: no track paint, the line alone */
  pointer-events: none;
}
.scroll-progress-fill {
  width: 100%;
  height: 100%;
  background: var(--accent);          /* kit: sanctuary red, a small saturated moment */
  transform: scaleX(0);
  transform-origin: left center;
  will-change: transform;
}

/* --------------------------------------------------------------------------
   003 Typewriter: hero h1 rotates the client's three real taglines.
   min-height reserves the 3-line hero geometry so the CTA never jumps.
   -------------------------------------------------------------------------- */
.hero-type { min-height: 264px; }     /* 3 lines at the ref 88px line height */
.type-caret {
  display: inline-block;
  width: 3px;
  height: .72em;
  margin-left: 8px;
  border-radius: 2px;
  background: currentColor;
  opacity: .55;                       /* subtle caret, quieter than the ink */
  vertical-align: -.04em;
  animation: caret-blink 1.1s steps(1) infinite;
}
@keyframes caret-blink { 50% { opacity: 0; } }

/* --------------------------------------------------------------------------
   013 Icon Slide In Button: accent-cta fill bubble blooms from the bottom,
   arrow slides in from the right, label shifts left; colors invert to the
   kit's primary CTA pairing (white on accent-cta, 5.86:1 AA).
   Catalog spring, exact: 0.5s cubic-bezier(.34, 1.08, .64, 1).
   -------------------------------------------------------------------------- */
.btn-slide {
  position: relative;
  overflow: hidden;
  isolation: isolate;                 /* keep the bubble inside this pill's paint order */
}
.btn-slide .btn-fill {
  position: absolute;
  left: 50%;
  bottom: -8px;
  width: 8px;
  height: 8px;
  border-radius: 100px;
  background: var(--accent-cta);      /* kit: primary pill fill where white text sits */
  transform: translateX(-50%);
  pointer-events: none;
  z-index: 0;
  transition: bottom .5s cubic-bezier(.34, 1.08, .64, 1),
              width  .5s cubic-bezier(.34, 1.08, .64, 1),
              height .5s cubic-bezier(.34, 1.08, .64, 1);
}
.btn-slide .btn-label {
  position: relative;
  z-index: 1;
  transition: color .5s cubic-bezier(.34, 1.08, .64, 1),
              transform .5s cubic-bezier(.34, 1.08, .64, 1);
}
.btn-slide .btn-icon {
  position: absolute;
  top: 50%;
  right: -26px;                       /* parked offscreen inside the clipped pill */
  transform: translateY(-50%);
  display: inline-flex;
  color: #FFFFFF;                     /* kit: white on accent-cta */
  z-index: 1;
  transition: right .5s cubic-bezier(.34, 1.08, .64, 1);
}
.btn-slide:hover .btn-fill,
.btn-slide:focus-visible .btn-fill {
  bottom: -64px;
  width: 112%;
  height: 200px;
}
.btn-slide:hover .btn-label,
.btn-slide:focus-visible .btn-label {
  color: #FFFFFF;
  transform: translateX(-9px);
}
.btn-slide:hover .btn-icon,
.btn-slide:focus-visible .btn-icon { right: 16px; }
.btn-slide:hover { opacity: 1; }      /* the bubble is the hover state; kill the generic pill fade */

/* --------------------------------------------------------------------------
   016 AnimatedNumber: flat stats band on the deep world, real numbers only.
   No cards, no borders, no shadows; hierarchy by size at weight 400.
   -------------------------------------------------------------------------- */
.stats-band { padding: 170px 48px; }
.stats-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 48px;
  max-width: 1180px;
  margin: 0 auto;
  text-align: center;
}
.stat-num {
  font-size: 72px;                    /* display scale sibling, weight 400 per kit */
  font-weight: 400;
  line-height: 1.1;
  letter-spacing: -1.8px;
}
.stat-label {
  margin-top: 10px;
  font-size: 16px;
  color: var(--muted-ink);            /* rides the world flip tokens */
}

/* --------------------------------------------------------------------------
   Full product carousel: pastel TEXT cards (kit card fills, flat, r32) for
   the 6 non-photo lines; name + one-liner + sub-product pill tags.
   -------------------------------------------------------------------------- */
.slide-text {
  padding: 32px;
  justify-content: space-between;     /* .slide is already flex column */
}
.slide-name {
  font-size: 34px;
  font-weight: 400;                   /* kit: hierarchy by size at weight 400 */
  line-height: 1.15;
  letter-spacing: -0.8px;
}
.slide-desc {
  margin-top: 16px;
  font-size: 18px;
  line-height: 1.45;
  color: var(--muted-ink);
}
.card-dark .slide-desc { color: rgba(255, 255, 255, .72); } /* derived: ink-inverse muted on media-dark */
.tag-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 24px;
}
.tag-row li {
  display: inline-flex;
  align-items: center;
  height: 36px;
  padding: 0 16px;
  border-radius: 96px;                /* kit radius scale member: pill */
  background: rgba(26, 26, 26, .07);  /* Round-13: charcoal tint, same family as footer signup panel */
  color: var(--ink);
  font-size: 14px;
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   020 Interactive Gradient, CSS variant: coral-family glow blobs inside the
   CTA band. Pre-blurred layers moved by transform only (compositor); blob c
   follows the pointer via home.js on fine pointers.
   -------------------------------------------------------------------------- */
.cta-band { overflow: hidden; }       /* bound the blobs; the band is its own stacking context (inline z-index) */
.cta-glow {
  position: absolute;
  inset: 0;
  z-index: -1;                        /* behind the band's content, above the html world paint */
  pointer-events: none;
}
.cta-glow span {
  position: absolute;
  border-radius: 50%;
  will-change: transform;
}
.cta-glow .glow-a {
  width: 52vw; height: 52vw;
  left: -14vw; top: -18vw;
  background: radial-gradient(circle, rgba(255, 255, 255, .35) 0%, rgba(255, 255, 255, 0) 65%); /* Round-13: white glow on red, subtle */
  animation: glow-drift-a 26s ease-in-out infinite alternate;
}
.cta-glow .glow-b {
  width: 44vw; height: 44vw;
  right: -12vw; bottom: -16vw;
  background: radial-gradient(circle, rgba(255, 255, 255, .28) 0%, rgba(255, 255, 255, 0) 65%);  /* Round-13: soft white glow */
  animation: glow-drift-b 34s ease-in-out infinite alternate;
}
.cta-glow .glow-c {
  width: 34vw; height: 34vw;
  left: 50%; top: 50%;
  margin: -17vw 0 0 -17vw;
  background: radial-gradient(circle, rgba(255, 255, 255, .22) 0%, rgba(255, 255, 255, 0) 62%); /* Round-13: white halo */
}
@keyframes glow-drift-a {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(9vw, 6vw, 0); }
}
@keyframes glow-drift-b {
  from { transform: translate3d(0, 0, 0); }
  to   { transform: translate3d(-8vw, -5vw, 0); }
}

/* --------------------------------------------------------------------------
   091 Dragable Ticker: one row of the 12 product lines as cream pill chips.
   Default (no JS / reduced motion): a static swipeable row. home.js promotes
   it to an infinite auto-scroll marquee with hand drag.
   -------------------------------------------------------------------------- */
.ticker-band { padding: 24px 0 72px; }
.ticker-clip {
  overflow-x: auto;                   /* no-JS fallback: hand-scrollable strip */
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  touch-action: pan-y;                /* horizontal gestures belong to the ticker */
}
.ticker-clip::-webkit-scrollbar { display: none; }
.ticker-clip.ticker-live {
  overflow: hidden;                   /* JS marquee owns the motion */
  cursor: grab;
}
.ticker-clip.ticker-live.dragging { cursor: grabbing; }
.ticker-row {
  display: flex;
  gap: 16px;                          /* catalog 091 native gap, exact */
  width: max-content;
  padding: 0 48px;
}
.ticker-live .ticker-row { padding: 0; }
.ticker-chip {
  display: inline-flex;
  align-items: center;
  height: 48px;
  padding: 0 22px;
  border-radius: 96px;
  background: var(--surface);         /* kit: cream chip, reads on every world */
  color: var(--ink);
  font-size: 16px;
  white-space: nowrap;
  transition: background-color .15s ease;
}
.ticker-chip:hover { background: var(--line); }
.ticker-live .ticker-chip { -webkit-user-drag: none; user-select: none; }

/* --------------------------------------------------------------------------
   Mobile (matches the styles.css 820 breakpoint)
   -------------------------------------------------------------------------- */
@media (max-width: 820px) {
  .hero-type { min-height: 93px; }    /* 3 lines at the ref 30.9375px mobile line height */
  .type-caret { width: 2px; margin-left: 5px; }

  .stats-band { padding: 96px 20px; }
  .stats-row { grid-template-columns: 1fr 1fr; gap: 40px 20px; }
  .stat-num { font-size: 44px; letter-spacing: -1px; }
  .stat-label { font-size: 14px; }

  .slide-text { padding: 24px; }
  .slide-name { font-size: 24px; letter-spacing: -0.5px; }
  .slide-desc { font-size: 15px; margin-top: 10px; }
  .tag-row { gap: 6px; margin-top: 16px; }
  .tag-row li { height: 32px; padding: 0 12px; font-size: 12px; }

  .ticker-band { padding: 16px 0 56px; }
  .ticker-chip { height: 44px; padding: 0 18px; }
  .ticker-row { padding: 0 20px; }

  .cta-glow .glow-a { width: 90vw; height: 90vw; left: -30vw; top: -24vw; }
  .cta-glow .glow-b { width: 80vw; height: 80vw; right: -26vw; bottom: -20vw; }
  .cta-glow .glow-c { display: none; } /* pointer blob is a fine-pointer feature */
}

/* --------------------------------------------------------------------------
   Reduced motion: statics only. The typewriter, count-ups, marquee, tilt and
   pointer blob are killed in home.js; CSS kills its own animations here.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .type-caret { display: none; }      /* first tagline stands, no caret theater */
  .btn-slide .btn-fill,
  .btn-slide .btn-label,
  .btn-slide .btn-icon { transition: none; }
  .cta-glow .glow-a, .cta-glow .glow-b { animation: none; }
  .scroll-progress-fill { transition: none; }
}

/* ==========================================================================
   2026-07-12 RICHNESS LAYER (Thomas: pages too plain, under-using the catalog).
   New placements, all re-tokened to design/brands/sanctuary.md:
   062 Border Beam (product cards), 085 Hover Image Zoom (product + easy media),
   069 ScrollIndicator (hero cue), 194 Halo Effect + 175 AnimatedTextGradient +
   190 Glow Counter Cards (stats band), 020 Interactive Gradient (tagged),
   076 Origin Button (CTA), 089 Animated Gradient BG (disclosure),
   058 Hover Text Highlight (footer links), 179 Paper Background (ticker),
   204 Lottie Player (CTA glyph, tagged). No em or en dashes.
   ========================================================================== */

/* main becomes the positioning context for the out-of-flow scroll cue */
#main-content { position: relative; }

/* --------------------------------------------------------------------------
   Line-of-cover cards: illustration-led. The generated cream-ground artwork
   fills a top media zone; name, one line and sub-product pills sit below on
   the pastel fill. No card is text-only anymore.
   -------------------------------------------------------------------------- */
.slide-ill { padding: 0; }                 /* the zone + body own their spacing */
.ill-zone { position: relative; overflow: hidden; }
.slide-ill > .ill-zone {
  height: 258px;                           /* ~45% of the 571px card; cover crops ~30px each edge, subjects safe */
  flex: 0 0 auto;
  background: #F9F1E2;                      /* matches the generated illustration cream ground so cover reads seamless */
}
.ill-img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
  transform-origin: center;
  transition: transform .5s var(--ease-house);  /* 085 zoom easing (calmed from native 2.5x) */
  will-change: transform;
}
/* 085 Hover Image Zoom: gentle cursor-origin scale, fine pointers get the origin from home.js */
[data-zoom]:hover .ill-img { transform: scale(1.09); }
.ill-body {
  flex: 1;
  display: flex;
  flex-direction: column;
  padding: 26px 30px 30px;
}
.ill-body .slide-desc { margin-top: 12px; }
.ill-body .tag-row { margin-top: auto; padding-top: 20px; } /* pills pinned to the card base */

/* --------------------------------------------------------------------------
   062 Border Beam (Glow Follow Border Card): a radial glow rides the card
   border ring, revealed on hover, following the cursor via --gx/--gy (home.js).
   Mask-xor cuts the interior so only the 1.5px ring lights up.
   -------------------------------------------------------------------------- */
.beam-ring {
  position: absolute;
  inset: 0;
  border-radius: 32px;                     /* matches the .slide radius */
  padding: 1.5px;
  z-index: 3;
  pointer-events: none;
  opacity: 0;
  transition: opacity .25s ease;
  background: radial-gradient(190px 190px at var(--gx, 50%) var(--gy, 50%),
              var(--accent) 0%, rgba(238, 29, 35, 0) 70%);
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
          mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
}
.slide:hover .beam-ring { opacity: .9; }
.card-dark .beam-ring {                      /* on the media-dark cards a cream glow reads better than red */
  background: radial-gradient(190px 190px at var(--gx, 50%) var(--gy, 50%),
              rgba(255, 255, 255, .85) 0%, rgba(255, 255, 255, 0) 70%);
}

/* --------------------------------------------------------------------------
   069 ScrollIndicator: mouse-pill + bouncing dot cue floating over the hero
   base, click-scrolls to the product lines. White over the dark hero media.
   -------------------------------------------------------------------------- */
.scroll-cue {
  position: absolute;
  left: 50%;
  top: 742px;                              /* hero: 28 margin + 805 height in main; sits ~90px above the card base */
  transform: translateX(-50%);
  z-index: 11;                             /* above the hero (z10), below the nav */
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  color: var(--ink-inverse);              /* cream over the dark media */
}
.scroll-cue-pill {
  width: 26px; height: 42px;
  border: 2px solid currentColor;
  border-radius: 20px;
  display: flex;
  justify-content: center;
  opacity: .7;
}
.scroll-cue-dot {
  width: 5px; height: 5px;
  margin-top: 8px;
  border-radius: 50%;
  background: currentColor;
  animation: cue-bounce 2.4s var(--ease-house) infinite;
}
.scroll-cue-word {
  font-size: 12px;
  letter-spacing: .2em;
  text-transform: uppercase;
  opacity: .68;
}
@keyframes cue-bounce {
  0%, 100% { transform: translateY(0); opacity: 1; }
  55%      { transform: translateY(13px); opacity: .25; }
}

/* --------------------------------------------------------------------------
   Stats band, richer: 194 Halo Effect backdrop + 175 AnimatedTextGradient
   eyebrow + 190 Glow Counter Cards. The count-up is still catalog 016.
   -------------------------------------------------------------------------- */
.stats-band { position: relative; overflow: hidden; }
.stats-halo { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.stats-halo .halo { position: absolute; border-radius: 50%; will-change: transform; }
.halo-1 {
  width: 42vw; height: 42vw; left: 4%; top: -14%;
  background: radial-gradient(circle, rgba(238, 29, 35, .18) 0%, rgba(238, 29, 35, 0) 65%); /* Round-13: red halo on charcoal deep world */
  animation: halo-drift-1 24s ease-in-out infinite alternate;
}
.halo-2 {
  width: 36vw; height: 36vw; right: 2%; top: 12%;
  background: radial-gradient(circle, rgba(255, 255, 255, .10) 0%, rgba(255, 255, 255, 0) 64%); /* Round-13: white halo */
  animation: halo-drift-2 30s ease-in-out infinite alternate;
}
.halo-3 {
  width: 30vw; height: 30vw; left: 44%; bottom: -16%;
  background: radial-gradient(circle, rgba(224, 224, 224, .14) 0%, rgba(224, 224, 224, 0) 62%); /* Round-13: gray line-tint halo */
  animation: halo-drift-3 27s ease-in-out infinite alternate;
}
@keyframes halo-drift-1 { from { transform: translate3d(0,0,0); } to { transform: translate3d(6vw, 5vw, 0); } }
@keyframes halo-drift-2 { from { transform: translate3d(0,0,0); } to { transform: translate3d(-5vw, 4vw, 0); } }
@keyframes halo-drift-3 { from { transform: translate3d(0,0,0); } to { transform: translate3d(4vw, -5vw, 0); } }

.stats-eyebrow { position: relative; z-index: 1; text-align: center; margin-bottom: 44px; font-size: 20px; }
.grad-text {
  background-image: linear-gradient(90deg, var(--ink-inverse), var(--world-bright), var(--line), var(--ink-inverse));
  background-size: 220% 220%;
  -webkit-background-clip: text;
          background-clip: text;
  color: transparent;
  animation: atg-shimmer 7s ease-in-out infinite; /* 175 sine path sampled at quarter points */
}
@keyframes atg-shimmer {
  0%   { background-position: 50% 50%; }
  25%  { background-position: 100% 100%; }
  50%  { background-position: 50% 50%; }
  75%  { background-position: 0% 0%; }
  100% { background-position: 50% 50%; }
}

.stats-row { position: relative; z-index: 1; }
.stat {
  position: relative;
  padding: 30px 18px 26px;
  border-radius: 24px;
  background: rgba(255, 255, 255, .045);   /* Round-13: faint white glass tile on the deep world */
  overflow: hidden;
  transition: transform .3s var(--ease-house), background-color .3s ease;
}
.stat-ring {
  position: absolute;
  inset: 0;
  border-radius: 24px;
  padding: 1.4px;
  pointer-events: none;
  opacity: .82;
  background: linear-gradient(115deg,
              rgba(238, 29, 35, 0) 22%, var(--accent) 46%, var(--accent) 54%, rgba(238, 29, 35, 0) 78%);
  background-size: 260% 100%;
  -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
          mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
  animation: ring-flow 7s linear infinite;
}
.stat:nth-child(2) .stat-ring { animation-delay: -1.6s; }
.stat:nth-child(3) .stat-ring { animation-delay: -3.2s; }
.stat:nth-child(4) .stat-ring { animation-delay: -4.8s; }
.stat:hover { transform: translateY(-3px); background: rgba(255, 255, 255, .08); }
.stat:hover .stat-ring { opacity: 1; }
@keyframes ring-flow { from { background-position: 0% 0; } to { background-position: 260% 0; } }

/* --------------------------------------------------------------------------
   076 Origin Button: a maroon fill circle blooms from the cursor entry point
   (--ox/--oy from home.js), the cream pill's label rides above and inverts.
   -------------------------------------------------------------------------- */
.origin-btn { position: relative; overflow: hidden; isolation: isolate; }
.origin-fill {
  position: absolute;
  left: var(--ox, 50%);
  top: var(--oy, 50%);
  width: 12px; height: 12px;
  border-radius: 50%;
  background: var(--world-deep);           /* maroon bloom under the cream pill */
  transform: translate(-50%, -50%) scale(0);
  transition: transform .55s cubic-bezier(.4, 0, .6, 1); /* 076 spring approx: slow bloom, accelerating fill */
  pointer-events: none;
  z-index: -1;                             /* above the pill fill, below the label */
}
.origin-btn:hover .origin-fill,
.origin-btn:focus-visible .origin-fill { transform: translate(-50%, -50%) scale(46); }
.origin-label, .origin-icon { position: relative; z-index: 1; display: inline-flex; transition: color .35s ease; }
.origin-btn:hover .origin-label,
.origin-btn:hover .origin-icon,
.origin-btn:focus-visible .origin-label,
.origin-btn:focus-visible .origin-icon { color: var(--ink-inverse); }
.origin-btn:hover { opacity: 1; }          /* the bloom is the hover; kill the generic pill fade */

/* --------------------------------------------------------------------------
   089 Animated Gradient BG: slow orbiting soft blobs behind the disclosure
   prose. Radial falloff (no filter blur) so it stays on the compositor.
   -------------------------------------------------------------------------- */
.disclosure { position: relative; overflow: hidden; }
.disc-gradient { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.disc-blob { position: absolute; border-radius: 50%; will-change: transform; }
.db-1 {
  width: 38vw; height: 38vw; left: 8%; top: 2%;
  background: radial-gradient(circle, rgba(200, 22, 27, .12) 0%, rgba(200, 22, 27, 0) 64%);
  animation: orbit-1 22s linear infinite;
}
.db-2 {
  width: 30vw; height: 30vw; right: 10%; top: 6%;
  background: radial-gradient(circle, rgba(224, 224, 224, .35) 0%, rgba(224, 224, 224, 0) 62%);
  animation: orbit-2 28s linear infinite;
}
.db-3 {
  width: 26vw; height: 26vw; left: 46%; bottom: -6%;
  background: radial-gradient(circle, rgba(26, 26, 26, .10) 0%, rgba(26, 26, 26, 0) 60%);
  animation: orbit-3 25s linear infinite;
}
.disclosure p { position: relative; z-index: 1; } /* prose above the wash */
/* Round-25 (review redline): dedicated complaints doorway under the disclosure
   prose. Ghost pill: hairline currentColor border so it reads on the bright
   world AND the no-JS light world; hover fill borrows the per-world chip
   token. Kit fonts and radii only, no new shadow. */
.disc-complaints {
  position: relative;
  z-index: 1;
  height: 52px;
  padding: 0 28px;
  background: transparent;
  border: 1px solid currentColor;
  color: inherit;
  line-height: 1;
  transition: background-color .2s ease, opacity .2s ease;
}
.disc-complaints .disc-complaints-icon { display: inline-flex; }
.disc-complaints:hover,
.disc-complaints:focus-visible { background: var(--chip-bg); opacity: 1; }
@media (max-width: 768px) {
  .disc-complaints { height: 48px; padding: 0 24px; }
}
@keyframes orbit-1 { from { transform: rotate(0)      translateX(3vw) rotate(0);       } to { transform: rotate(360deg)  translateX(3vw) rotate(-360deg);  } }
@keyframes orbit-2 { from { transform: rotate(0)      translateX(2.4vw) rotate(0);     } to { transform: rotate(-360deg) translateX(2.4vw) rotate(360deg); } }
@keyframes orbit-3 { from { transform: rotate(30deg)  translateX(2.8vw) rotate(-30deg);} to { transform: rotate(390deg)  translateX(2.8vw) rotate(-390deg); } }

/* --------------------------------------------------------------------------
   058 Hover Text Highlight: accent underline wipes in left to right on the
   footer link columns. Pure CSS, no runtime.
   -------------------------------------------------------------------------- */
.hl-links a { position: relative; }
.hl-links a::after {
  content: "";
  position: absolute;
  left: 0; bottom: -2px;
  width: 100%; height: 2px;
  border-radius: 2px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .3s var(--ease-house);
}
.hl-links a:hover::after,
.hl-links a:focus-visible::after { transform: scaleX(1); }

/* 2026-07-12: 179 Paper Background removed. A paper texture is a boxed section
   backdrop, which the seamless-page directive bans; the ticker sits on the flat
   bright world with no texture now. Kept position:relative for the drag layer. */
.ticker-band { position: relative; }

/* --------------------------------------------------------------------------
   Mobile (matches the styles.css 820 breakpoint)
   -------------------------------------------------------------------------- */
@media (max-width: 820px) {
  .slide-ill > .ill-zone { height: 190px; }   /* mobile card 448px */
  .ill-body { padding: 18px 20px 20px; }
  .ill-body .slide-desc { margin-top: 8px; }
  .ill-body .tag-row { padding-top: 14px; }

  .scroll-cue { top: calc(100vh - 96px); }    /* mobile hero is calc(100vh - 4px) tall */
  .scroll-cue-pill { width: 24px; height: 38px; }
  .scroll-cue-word { font-size: 11px; }

  .stats-eyebrow { font-size: 16px; margin-bottom: 28px; }
  .stat { padding: 22px 12px 20px; border-radius: 20px; }
  .stat-ring { border-radius: 20px; }
}

/* --------------------------------------------------------------------------
   Reduced motion: freeze every new animation, keep every static fallback.
   home.js also skips the cursor-follow work (beam glow, zoom origin, origin
   bloom) under reduced motion / coarse pointers.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .ill-img { transition: none; }
  [data-zoom]:hover .ill-img { transform: none; }
  .beam-ring { transition: none; }
  .scroll-cue-dot { animation: none; }
  .grad-text { animation: none; }              /* holds the coral mid-stop, high contrast on the deep world */
  .stat-ring { animation: none; }
  .stat:hover { transform: none; }
  .halo-1, .halo-2, .halo-3 { animation: none; }   /* static halos remain (194 fallback) */
  .disc-blob { animation: none; }                  /* static wash remains (089 fallback) */
  .origin-fill { transition: none; }
  .hl-links a::after { transition: none; }
}


/* catalog 055 Back To Top (2026-07-12) */
.to-top {
  position: fixed; right: 24px; bottom: 24px; z-index: 80;
  width: 48px; height: 48px; border-radius: 50%;
  background: var(--accent-cta); color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  opacity: 0; transform: translateY(12px); pointer-events: none;
  box-shadow: 0 4px 16px rgba(26, 26, 26, .25);
  transition: opacity .25s var(--ease-house), transform .25s var(--ease-house);
}
.to-top.show { opacity: 1; transform: none; pointer-events: auto; }
.to-top:hover { background: #AE1217; }
@media (prefers-reduced-motion: reduce) { .to-top { transition: opacity .01s; } }


/* ==========================================================================
   2026-07-12 DEPTH LAYER (Thomas: pages under-developed; add the reviews we
   never had, and restore the component count as CONTENT-level motion, not
   section backdrops). New, all re-tokened to design/brands/sanctuary.md:
   162 Dia Word Carousel + 185 HighlightText + 127 Flow Marquee (breadth band),
   201 Draggable Testimonials + 152 Digit Up (reviews). No boxed backdrops.
   No em or en dashes.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Breadth band ("Why Sanctuary"): flat light-world editorial beat naming the
   12 lines honestly. Text columns are centered and tight; no backdrop.
   -------------------------------------------------------------------------- */
.breadth { padding: 96px 48px; text-align: center; }
.breadth-eyebrow {
  font-size: 16px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--muted-ink);
  margin-bottom: 22px;
}
.breadth-head { text-align: center; }
.breadth-lead {
  margin: 32px auto 0;
  max-width: 860px;
  font-size: 20px;
  line-height: 1.6;
  color: var(--muted-ink);
}

/* 162 Dia Word Carousel: the trailing word rolls vertically on its own centered
   line. The sizer reserves the widest word's width so the line never reflows;
   home.js clones word one to make the wrap seamless. */
.word-carousel {
  position: relative;
  display: inline-block;
  height: 1.1em;                 /* matches the .display line height */
  overflow: hidden;
  vertical-align: bottom;
  color: var(--accent-cta);      /* saturated brand moment, AA at display size */
  text-align: center;
}
.wc-sizer { visibility: hidden; display: inline-block; }
.wc-track {
  position: absolute;
  left: 0; right: 0; top: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  transition: transform .6s var(--ease-house);
  will-change: transform;
}
.wc-word { height: 1.1em; line-height: 1.1; white-space: nowrap; }

/* 185 HighlightText: a highlighter band wipes in under the breadth phrase. The
   default (no-JS / reduced motion) is the filled state; home.js seeds hl-pending
   (zero width) only when motion is allowed, then hl-in wipes it to full. */
.hl-mark {
  color: var(--ink);            /* darker than the muted lead, the emphasis pops */
  background: linear-gradient(rgba(238, 29, 35, .35) 0 0) no-repeat left center;
  background-size: 100% 60%;    /* sits low like a real marker stroke */
  padding: 0 .06em;
  border-radius: 2px;
  box-decoration-break: clone;
  -webkit-box-decoration-break: clone;
  transition: background-size .7s var(--ease-house);
}
.hl-mark.hl-pending { background-size: 0% 60%; }
.hl-mark.hl-in { background-size: 100% 60%; }

/* 127 Flow Marquee: real credibility facts scroll as one slow strip, full-bleed
   to the page edges with a soft edge fade. Two identical sets, translateX -50%
   loops seamlessly. Distinct from the pill-chip product ticker (091). */
.flow-marquee {
  margin: 56px -48px 0;
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 8%, #000 92%, transparent 100%);
          mask-image: linear-gradient(90deg, transparent 0, #000 8%, #000 92%, transparent 100%);
}
.fm-track {
  display: inline-flex;
  align-items: center;
  gap: 26px;
  width: max-content;
  padding-left: 26px;
  animation: fm-scroll 46s linear infinite;
  will-change: transform;
}
.flow-marquee:hover .fm-track { animation-play-state: paused; }
.fm-item { font-size: 16px; color: var(--muted-ink); white-space: nowrap; }
.fm-dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--accent);
  opacity: .7;
  flex: 0 0 auto;
}
@keyframes fm-scroll { from { transform: translateX(0); } to { transform: translateX(-50%); } }

/* --------------------------------------------------------------------------
   Reviews (deep world): cream quote cards, honest team framing. NO backdrop.
   -------------------------------------------------------------------------- */
.reviews { padding: 24px 48px 120px; }
.reviews-head { max-width: 820px; margin: 0 auto 56px; text-align: center; }
.reviews-eyebrow {
  font-size: 16px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--muted-ink);
  margin-bottom: 20px;
}
.reviews-title { text-align: center; }
.reviews-rating { display: inline-flex; align-items: baseline; gap: 12px; margin-top: 28px; }
.rating-num {
  font-size: 88px;
  font-weight: 400;
  line-height: 1;
  letter-spacing: -2px;
  color: var(--ink-inverse);
}
.rating-of { font-size: 20px; color: var(--muted-ink); }
.rating-stars { font-size: 22px; letter-spacing: 3px; color: var(--card-coral); }
.reviews-lead {
  margin: 28px auto 0;
  max-width: 640px;
  font-size: 20px;
  line-height: 1.6;
  color: var(--muted-ink);
}

/* 152 Digit Up odometer: each numeric digit is a column of 0..9 that rolls to
   its target; home.js builds the columns only under motion, so the static 4.9
   in the markup covers no-JS and reduced motion. */
.du-wrap { display: inline-flex; align-items: flex-end; }
.du-col { display: inline-block; height: 1em; overflow: hidden; vertical-align: bottom; }
.du-strip {
  display: flex;
  flex-direction: column;
  transition: transform 1.1s var(--ease-house);
  will-change: transform;
}
.du-cell { height: 1em; line-height: 1; text-align: center; }
.du-static { display: inline-block; }

/* 201 Draggable Testimonials: a horizontal deck, all three visible on desktop,
   swipe/drag on narrower views. Cream cards on the deep world; role labels make
   the staff status unmistakable. */
.reviews-deck { max-width: 1200px; margin: 0 auto; }
.testi-row {
  display: flex;
  gap: 28px;
  justify-content: center;       /* centered when the three fit; scrolls when they do not */
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 6px 0 10px;
}
.testi-row::-webkit-scrollbar { display: none; }
.testi-row.drag-scroll { cursor: grab; }
.testi-row.drag-scroll.dragging { cursor: grabbing; }
.testi-card {
  flex: 0 0 clamp(280px, 33%, 372px);
  scroll-snap-align: center;
  background: var(--surface);
  color: var(--ink);
  border-radius: 32px;
  padding: 34px 32px 30px;
  display: flex;
  flex-direction: column;
  min-height: 320px;
}
.testi-mark {
  font-family: Georgia, "Times New Roman", serif;
  font-size: 64px;
  line-height: .5;
  height: 34px;
  color: var(--card-coral);
}
.testi-quote { margin-top: 14px; font-size: 24px; line-height: 1.35; font-weight: 400; }
.testi-by { margin-top: auto; padding-top: 28px; display: flex; flex-direction: column; gap: 3px; }
.testi-name { font-size: 17px; }
/* Round-13: muted on the gray card is the charcoal muted tint, not the deep-world
   white token that the section otherwise inherits (that would be white on gray). */
.testi-role { font-size: 15px; color: rgba(26, 26, 26, .68); }

/* --------------------------------------------------------------------------
   Mobile (matches the styles.css 820 breakpoint)
   -------------------------------------------------------------------------- */
@media (max-width: 820px) {
  .breadth { padding: 64px 20px; }
  .breadth-lead { font-size: 16px; margin-top: 24px; }
  .flow-marquee { margin: 40px -20px 0; }
  .fm-item { font-size: 14px; }

  .reviews { padding: 8px 20px 80px; }
  .reviews-head { margin-bottom: 36px; }
  .reviews-lead { font-size: 16px; }
  .reviews-rating { margin-top: 20px; }
  .rating-num { font-size: 60px; }
  .testi-row {
    justify-content: flex-start;   /* one card per view, swipe through */
    gap: 16px;
    margin: 0 -20px;
    padding: 6px 20px 12px;
  }
  .testi-card { flex: 0 0 82vw; min-height: 280px; padding: 26px 24px 24px; }
  .testi-quote { font-size: 20px; }
}

/* --------------------------------------------------------------------------
   Reduced motion: freeze every new animation; every real value stays readable.
   home.js also skips the word roll, the digit roll and the highlight seed under
   reduced motion, so the statics in the markup are what render.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .wc-track { transition: none; }
  .du-strip { transition: none; }
  .hl-mark { transition: none; }
  .fm-track { animation: none; }
  .flow-marquee { overflow-x: auto; }   /* static strip stays hand-scrollable */
}


/* Section entrance reveals (2026-07-12): cool block-level scroll-in */
.reveal { opacity: 0; transform: translateY(46px); transition: opacity .8s var(--ease-house), transform .9s var(--ease-house); transition-delay: var(--rd, 0s); will-change: opacity, transform; }
.reveal.in { opacity: 1; transform: none; }
h2.display.reveal { clip-path: inset(0 0 14% 0); transition: opacity .8s var(--ease-house), transform .9s var(--ease-house), clip-path .95s var(--ease-house); transition-delay: var(--rd, 0s); }
h2.display.reveal.in { clip-path: inset(0 0 -14% 0); }
@media (prefers-reduced-motion: reduce) { .reveal, h2.display.reveal { opacity: 1; transform: none; clip-path: none; transition: none; } }


/* --------------------------------------------------------------------------
   Round-13 (2026-07-13): Agriculture / Tobacco spotlight.
   Full-width deep-world beat between the product carousel and the easy-buy
   section. Names both crops honestly and points at the services page. Two
   real illustrations (tobacco + agriculture) sit side by side above the CTA
   pills. No hand-drawn glyphs, no invented facts.
   -------------------------------------------------------------------------- */
.ag-spotlight {
  position: relative;
  background: var(--world-deep);
  color: var(--ink-inverse);
  padding: 112px 48px;
  text-align: center;
  overflow: hidden;
}
.ag-spotlight .ag-inner {
  position: relative;
  max-width: 1080px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.ag-spotlight .eyebrow {
  font-size: 14px;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--muted-ink);
  margin-bottom: 22px;
}
.ag-spotlight .display { margin: 8px 0 28px; }
.ag-spotlight .ag-lead {
  max-width: 56ch;
  margin: 0 auto 40px;
  font-size: 20px;
  line-height: 1.55;
  color: rgba(255, 255, 255, .82);
}
.ag-spotlight .ag-art {
  display: flex;
  justify-content: center;
  gap: 24px;
  width: 100%;
  max-width: 720px;
  margin: 0 auto 40px;
}
.ag-spotlight .ag-ill {
  flex: 1 1 0;
  width: 100%;
  max-width: 340px;
  height: auto;
  border-radius: 24px;
  background: var(--card-cream);
  padding: 8px;
  object-fit: contain;
}
.ag-spotlight .ag-pills {
  display: flex;
  gap: 16px;
  justify-content: center;
  flex-wrap: wrap;
}
@media (max-width: 820px) {
  .ag-spotlight { padding: 72px 20px; }
  .ag-spotlight .ag-lead { font-size: 16px; }
  .ag-spotlight .ag-art { flex-direction: column; align-items: center; gap: 16px; }
  .ag-spotlight .ag-ill { max-width: 260px; }
}

/* --------------------------------------------------------------------------
   Round-24 (2026-08-22, client ask 7): lead covers. The four lines the client
   asked us to put front and centre (Agriculture, Scholar Care, Motor, Bonds),
   a static 2x2 grid directly after the hero. Deliberately NOT a carousel:
   prominence means all four visible at once. Cards compose the existing
   ill-zone / ill-body / tag-row vocabulary; 085 zoom and 062 beam bind through
   home.js's global [data-zoom] / [data-glow-card] hooks, so no new JS.
   -------------------------------------------------------------------------- */
.lead-covers { max-width: 1440px; margin: 0 auto; padding: 128px 48px 32px; }
.lc-head { display: flex; flex-direction: column; align-items: flex-start; gap: 22px; margin-bottom: 56px; }
.lc-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 32px; }
.lc-card {
  position: relative;
  display: flex;
  flex-direction: column;
  border-radius: 32px;               /* kit: card radius 32, border none, shadow none */
  overflow: hidden;
  min-height: 520px;
}
.lc-card > .ill-zone { height: 258px; flex: 0 0 auto; background: #F9F1E2; } /* same cream seam as the carousel art zones */
.lc-card:hover .beam-ring { opacity: .9; }  /* the reveal is .slide-scoped in the carousel; extended to this card family */
.lc-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 18px;
  align-self: flex-start;
  font-weight: 500;
  color: inherit;
  text-decoration: none;
  border-bottom: 1.5px solid currentColor;
  padding-bottom: 2px;
}
.lc-link:hover { color: var(--accent-cta); }
.lc-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
@media (max-width: 900px) {
  .lead-covers { padding: 72px 20px 8px; }
  .lc-grid { grid-template-columns: 1fr; gap: 20px; }
  .lc-card { min-height: 0; }
  .lc-card > .ill-zone { height: 200px; }
  .lc-head { margin-bottom: 36px; }
}
