/* =========================================================
   Vupo shared theme — design tokens + cross-page components.
   Used by index.html AND blog/article.html; pair it with
   vupo-tailwind.js (the Tailwind config reads the same tokens).
   Page-specific CSS (ticker, gauge, hero entrance, …) stays
   inline in each page.
   ========================================================= */

/* =========================================================
   DESIGN TOKENS — single source of truth for the palette.

   Each colour is declared ONCE, as a space-separated rgb triplet:
   that form is what Tailwind needs to support alpha modifiers
   (bg-primary/10, border-secondary/40, …). The familiar --primary
   /--accent/… hex tokens are *derived* from those triplets, so
   plain CSS can use var(--primary) and can never fall out of sync
   with what Tailwind paints.

   To re-skin the page, edit only the five triplets below.
   ========================================================= */
:root {
  --text-rgb:       53  34  16;   /* #352210  deep warm brown — body copy   */
  --bg-rgb:        250 247 245;   /* #faf7f5  warm off-white — page canvas  */
  --primary-rgb:    41 194  30;   /* #29c21e  Energetic Green — brand       */
  --secondary-rgb:  22 239 243;   /* #16eff3  Bright Cyan/Teal — glows      */
  --accent-rgb:    232 114  17;   /* #e87211  Electric Orange — CTAs        */

  /* derived — do not edit directly */
  --text:      rgb(var(--text-rgb));
  --bg:        rgb(var(--bg-rgb));
  --primary:   rgb(var(--primary-rgb));
  --secondary: rgb(var(--secondary-rgb));
  --accent:    rgb(var(--accent-rgb));

  scroll-behavior: smooth;
}

body {
  background-color: var(--bg);
  color: var(--text);
  overflow-x: hidden;
}

/* ---- grain texture over everything, very subtle ---- */
.grain::before {
  content: '';
  position: fixed; inset: 0;
  pointer-events: none; z-index: 60;
  opacity: 0.35;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='matrix' values='0 0 0 0 0.208 0 0 0 0 0.133 0 0 0 0 0.063 0 0 0 0.05 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ---- gradient text ----
   Both gradients stay within shades that clear 3:1 on --bg, since they
   only ever paint large display type (30px+ / font-black). ---- */
.text-gradient-brand {
  background: linear-gradient(120deg, #0F5C0A 0%, #1FA015 45%, #C85E0B 110%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.text-gradient-logo {
  background: linear-gradient(100deg, #0A3D07, #1FA015);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}

/* ---- ambient blobs ---- */
.blob {
  position: absolute; border-radius: 9999px;
  filter: blur(80px); pointer-events: none; z-index: -1;
}

/* ---- glowing pillar cards ---- */
.pillar-card { position: relative; transition: transform .35s cubic-bezier(.2,.9,.3,1.2), box-shadow .35s ease; }
.pillar-card::before {
  content: ''; position: absolute; inset: -1.5px; border-radius: inherit; z-index: -1;
  background: linear-gradient(140deg, var(--glow-a), var(--glow-b));
  opacity: .35; transition: opacity .35s ease;

  /* Mask everything but the 1.5px rim. The z-index:-1 alone isn't enough:
     the moment anything turns the card into a stacking context — .reveal's
     transform, or the :hover lift — a negative-z pseudo-element paints ABOVE
     the element's own background instead of behind it, and the gradient
     washes across the card, dragging the body copy well below AA contrast.
     Masking the interior away makes the rim the only thing that can ever
     paint, in or out of a stacking context. */
  padding: 1.5px;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
}
.pillar-card:hover { transform: translateY(-8px); }
.pillar-card:hover::before { opacity: 1; }

/* ---- CTA button ---- */
.btn-cta {
  transition: transform .25s cubic-bezier(.2,.9,.3,1.4), box-shadow .25s ease, background-color .25s ease;
}
.btn-cta:hover { transform: translateY(-2px) scale(1.02); }
.btn-cta:active { transform: translateY(0) scale(.98); }

/* ---- link underline slide ---- */
.link-slide { position: relative; }
.link-slide::after {
  content: ''; position: absolute; inset-inline-start: 0; bottom: -2px;
  width: 100%; height: 2px; background: currentColor;
  transform: scaleX(0); transform-origin: center; transition: transform .3s ease;
}
.link-slide:hover::after { transform: scaleX(1); }

/* ---- site menu, desktop: the current page (aria-current, set by
   site-nav.js) is bold green with a 3px bar sitting ON the header's bottom
   border. The links stretch to the header row's height, so the bar's
   `bottom` is exactly the row's vertical padding (py-3.5 = .875rem). ---- */
.nav-link { position: relative; transition: color .2s ease; }
.nav-link[aria-current="page"] { color: #0F5C0A; font-weight: 800; }
.nav-link[aria-current="page"]::after {
  content: ''; position: absolute; inset-inline: 0; bottom: -.875rem;
  height: 3px; border-radius: 9999px; background: var(--primary);
}
/* emergency stays red even as the current page */
.nav-link-danger[aria-current="page"] { color: #8F1717; }
.nav-link-danger[aria-current="page"]::after { background: #D62828; }

/* pulsing red dot beside "emergency vets" (desktop + phone menu) */
.nav-ping::after {
  content: ''; position: absolute; inset: 0; border-radius: 9999px;
  background: #D62828; animation: ping-soft 1.8s cubic-bezier(0,0,.2,1) infinite;
}

/* ---- site menu (phones/tablets): a native <details> ---- */
.site-menu > summary::-webkit-details-marker { display: none; }
.site-menu .site-menu-close { display: none; }
.site-menu[open] .site-menu-open { display: none; }
.site-menu[open] .site-menu-close { display: block; }
.site-menu[open] > summary { background: var(--text); border-color: var(--text); color: #fff; }
.site-menu > summary:focus-visible { outline: 3px solid rgb(var(--secondary-rgb)); outline-offset: 3px; }

/* ---- site search (site-search.js) ----
   Below xl (1280px) the header row has no room for an input (the training page
   carries a WhatsApp button too): a 40px button opens the bar as a full-width
   layer under the header, positioned against the sticky <header> exactly like
   the phone menu. From xl the input sits in the row, and the results layer
   still spans the header's full width. Plain CSS on purpose — the rows are
   built in JS, and Tailwind's Play CDN would paint them a frame late. */
.site-search[hidden], .site-search [hidden] { display: none !important; }
.site-search { display: flex; align-items: center; }
.site-search-toggle {
  display: flex; height: 2.5rem; width: 2.5rem; flex: none; align-items: center; justify-content: center;
  border-radius: 9999px; border: 1px solid #ADEDA4; background: #fff; color: var(--text); cursor: pointer;
  box-shadow: 0 4px 24px -6px rgb(var(--text-rgb) / .12), 0 2px 8px -4px rgb(var(--text-rgb) / .08);
  transition: box-shadow .2s ease;
}
.site-search-toggle:hover { box-shadow: 0 24px 48px -12px rgb(var(--text-rgb) / .22), 0 8px 20px -8px rgb(var(--text-rgb) / .14); }
.site-search-toggle:focus-visible { outline: 3px solid rgb(var(--secondary-rgb)); outline-offset: 3px; }
.site-search-toggle svg { height: 1.25rem; width: 1.25rem; }
.site-search-toggle-close { display: none; }
.site-search.is-open .site-search-toggle { background: var(--text); border-color: var(--text); color: #fff; }
.site-search.is-open .site-search-toggle-open { display: none; }
.site-search.is-open .site-search-toggle-close { display: block; }

.site-search-bar {
  display: none; position: absolute; inset-inline: 0; top: 100%;
  border-bottom: 1px solid #D6F6D1; background: #fff; padding: .75rem 1.25rem;
  box-shadow: 0 24px 48px -12px rgb(var(--text-rgb) / .22), 0 8px 20px -8px rgb(var(--text-rgb) / .14);
}
.site-search.is-open .site-search-bar { display: block; }
.site-search-field { position: relative; margin-inline: auto; max-width: 48rem; }
.site-search-icon {
  position: absolute; inset-inline-start: .85rem; top: 50%; height: 1.1rem; width: 1.1rem;
  transform: translateY(-50%); color: rgb(var(--text-rgb) / .55); pointer-events: none;
}
.site-search-input {
  -webkit-appearance: none; appearance: none;
  display: block; width: 100%; height: 2.75rem; border-radius: 9999px;
  border: 1px solid #ADEDA4; background: var(--bg); color: var(--text);
  padding-inline: 2.5rem 1rem;
  font: inherit; font-size: 16px; /* under 16px iOS zooms the page on focus */
  transition: width .2s ease, border-color .2s ease, box-shadow .2s ease;
}
.site-search-input::placeholder { color: rgb(var(--text-rgb) / .55); }
.site-search-input::-webkit-search-cancel-button { cursor: pointer; }
.site-search-input:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 4px rgb(var(--primary-rgb) / .2); }

.site-search-panel {
  max-height: calc(100vh - 9rem); max-height: calc(100dvh - 9rem);
  overflow-y: auto; overscroll-behavior: contain; margin-top: .5rem;
}
.site-search-inner { margin-inline: auto; max-width: 48rem; padding-block: .25rem .5rem; }
.site-search-group + .site-search-group { margin-top: .75rem; border-top: 1px solid rgb(var(--text-rgb) / .06); padding-top: .75rem; }
.site-search-group-label { padding-inline: .75rem; font-size: .75rem; font-weight: 700; letter-spacing: .02em; color: rgb(var(--text-rgb) / .6); }
.site-search-option {
  display: block; margin-top: .25rem; border-radius: .9rem; padding: .6rem .75rem;
  color: var(--text); text-decoration: none; cursor: pointer;
}
.site-search-option[aria-selected="true"] { background: #EDFBEB; box-shadow: inset 0 0 0 1px #ADEDA4; }
.site-search-option:focus-visible { outline: 3px solid rgb(var(--secondary-rgb)); outline-offset: 2px; }
.site-search-crumbs { display: block; font-size: .75rem; font-weight: 600; color: rgb(var(--text-rgb) / .6); }
.site-search-option[data-type="center"] .site-search-crumbs { color: #8F1717; }
/* the page a guide result lives on — its own chip, because two pages can hold
   a section with the same title and this is what tells them apart */
.site-search-crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: .15rem .5rem; }
.site-search-page {
  flex: none; border-radius: 9999px; background: #D6F6D1; color: #0F5C0A;
  padding: .05rem .5rem; font-size: .7rem; font-weight: 800;
}
.site-search-title { display: block; font-weight: 800; line-height: 1.35; }
.site-search-snippet { display: block; margin-top: .15rem; font-size: .875rem; line-height: 1.5; color: rgb(var(--text-rgb) / .72); }
.site-search-option mark { background: #D6F6D1; color: inherit; border-radius: .2rem; padding-inline: .1rem; }
.site-search-badge {
  display: inline-block; vertical-align: middle; border-radius: 9999px; background: rgb(var(--text-rgb) / .08);
  padding: .05rem .4rem; font-size: .65rem; font-weight: 700; letter-spacing: .04em; color: rgb(var(--text-rgb) / .7);
}
.site-search-note { padding: .75rem; font-size: .9rem; color: rgb(var(--text-rgb) / .75); }
.site-search-archive { font-weight: 700; color: #15800E; text-decoration: underline; text-underline-offset: 4px; }

@media (min-width: 1280px) {
  .site-search-toggle { display: none; }
  .site-search-bar {
    display: block; position: static; border: 0; background: none; padding: 0; box-shadow: none;
  }
  .site-search-input { width: 11.25rem; height: 2.5rem; font-size: 15px; }
  .site-search-bar:focus-within .site-search-input { width: 16rem; }
  /* the results still hang under the whole header, anchored to <header> */
  .site-search-panel {
    position: absolute; inset-inline: 0; top: 100%; margin-top: 0;
    max-height: calc(100vh - 5rem); max-height: calc(100dvh - 5rem);
    border-bottom: 1px solid #D6F6D1; background: #fff; padding: .5rem 1.25rem;
    box-shadow: 0 24px 48px -12px rgb(var(--text-rgb) / .22), 0 8px 20px -8px rgb(var(--text-rgb) / .14);
  }
}

@media (prefers-reduced-motion: reduce) {
  .site-search-input, .site-search-toggle { transition: none; }
}

/* phone numbers and ages line up and never reorder inside RTL text. Lives here
   (not guides.css) because site-search results show phone numbers on every page. */
.num { font-variant-numeric: tabular-nums; unicode-bidi: isolate; direction: ltr; display: inline-block; }

/* ---- scroll reveal ---- */
.reveal { opacity: 0; transform: translateY(32px); transition: opacity .8s cubic-bezier(.2,.8,.3,1), transform .8s cubic-bezier(.2,.8,.3,1); }
.reveal.is-visible { opacity: 1; transform: translateY(0); }
.reveal[data-delay="1"] { transition-delay: .12s; }
.reveal[data-delay="2"] { transition-delay: .24s; }
.reveal[data-delay="3"] { transition-delay: .36s; }

/* ---- pulsing beta dot ---- */
@keyframes ping-soft { 0% { transform: scale(1); opacity: .9; } 80%, 100% { transform: scale(2.4); opacity: 0; } }
.ping-dot::after {
  content: ''; position: absolute; inset: 0; border-radius: 9999px;
  background: var(--primary); animation: ping-soft 1.8s cubic-bezier(0,0,.2,1) infinite;
}

/* no-JS fallback — never leave content invisible */
.no-js .reveal, .no-js .rise { opacity: 1; transform: none; animation: none; }

@media (prefers-reduced-motion: reduce) {
  .rise, .reveal, .floaty, .floaty-2, .marquee-track, .ping-dot::after, .nav-ping::after { animation: none !important; transition: none !important; opacity: 1 !important; transform: none !important; }
  .gauge-arc { transition: none; }
  :root { scroll-behavior: auto; }
}
