/* ============================================================================
   SARART · BASE — reset, typography, canonical keyframes and reusable utilities
   (grain / vignette / glow / ghost-frame / gold button). Ported 1:1 from the
   mockup so every page phase can build on the same primitives.
   ============================================================================ */

*,
*::before,
*::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-weight: 400;
  /* 1.5, NOT 1.6: this is the value every element that does not declare its own
     line-height inherits, and the mockup renders at 1.5 (Tailwind preflight sets
     it on <html>). Measured across home + shop + about, 1.5 lands 39 text blocks
     exactly on the mockup that 1.6 missed by 1–26px, and breaks none. */
  line-height: 1.5;
  overflow-x: clip;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img, video, svg { max-width: 100%; display: block; }
/* <picture> only selects the source — it must not add a box of its own, or the
   absolutely-positioned .hero__img would resolve against it instead of the tile. */
picture { display: contents; }
a { color: inherit; }
button { font-family: inherit; }
/* line-height 1.5, same as body: in the mockup a heading INHERITS the global
   1.5 unless its own component sets something tighter, and nearly every heading
   here does (1.03–1.12). A 1.06 default silently overrode the contract for the
   few that don't — it was squashing the Testimonials title ("Worn & Loved":
   54.3px vs the mockup's 76.8px) and every product-card name that wraps to two
   lines (39.8px vs 47.2px). Set a tighter line-height per component, not here. */
h1, h2, h3, h4 { font-family: var(--font-serif); font-weight: 600; margin: 0; line-height: 1.5; }

/* Skip link (a11y) */
.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: calc(var(--z-preloader) + 1);
  background: var(--gold); color: var(--gold-ink); padding: 10px 16px; border-radius: 0 0 var(--r-md) 0; font-weight: 700;
}
.skip-link:focus { left: 0; }

/* ---- Responsive visibility helpers (ported verbatim from the mockup) ----
   `.hide-mob` is hidden by default and becomes a FLEX row from 880px up — the
   desktop-only rows that use it (navbar menu, shop toolbar) are all flex, and
   the mockup relies on that: without it the shop toolbar stops being a flex row
   and "Sort by" drops to a second line. */
.hide-mob { display: none !important; }
@media (min-width: 880px) {
  .hide-mob { display: flex !important; }
  .hide-desk { display: none !important; }
}

/* ---- Shared eyebrow ---- */
.eyebrow {
  text-transform: uppercase;
  letter-spacing: var(--tracking-eyebrow);
  font-size: var(--fs-eyebrow);
  font-weight: 700;
  color: var(--gold);
}

/* ============================================================================
   KEYFRAMES (ported verbatim from globals.css of the mockup)
   ============================================================================ */
@keyframes blink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }
@keyframes marq { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@keyframes bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(7px); } }
@keyframes preLogo { 0% { transform: translateY(8px) scale(0.97); letter-spacing: 0.5em; } 100% { transform: none; letter-spacing: 0.04em; } }
@keyframes preBar { from { width: 0; } to { width: 100%; } }
@keyframes smsPulse {
  0% { transform: scale(1); opacity: 0.5; }
  70% { transform: scale(1.75); opacity: 0; }
  100% { transform: scale(1.75); opacity: 0; }
}
@keyframes glowA { 0%, 100% { transform: translate(0, 0) scale(1); } 50% { transform: translate(6%, 4%) scale(1.14); } }
@keyframes glowB { 0%, 100% { transform: translate(0, 0) scale(1.05); } 50% { transform: translate(-5%, -3%) scale(0.92); } }
@keyframes glowC { 0%, 100% { transform: translate(-50%, -50%) scale(1); } 50% { transform: translate(-46%, -54%) scale(1.12); } }
@keyframes grainshift {
  0%, 100% { transform: translate(0, 0); }
  25% { transform: translate(-4%, 2%); }
  50% { transform: translate(3%, -3%); }
  75% { transform: translate(2%, 4%); }
}
@keyframes goldBreath {
  0%, 100% { opacity: 0.35; transform: translate(-50%, -50%) scale(1); }
  50% { opacity: 0.6; transform: translate(-50%, -50%) scale(1.12); }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .site-preloader { display: none !important; }
  .sms-pulse, .u-glow, .u-grain { animation: none !important; }
  .reveal { opacity: 1 !important; transform: none !important; }
}

/* ============================================================================
   BACKGROUND-TREATMENT UTILITIES (grain / vignette / glow)
   Layer these as absolutely-positioned children (aria-hidden) inside a
   position:relative section, exactly like the mockup.
   ============================================================================ */
.u-layer { position: absolute; inset: 0; z-index: 0; pointer-events: none; }

/* Fine film grain (feTurbulence, inlined) — set opacity via --grain-opacity. */
.u-grain {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  opacity: var(--grain-opacity, 0.045);
}

/* Framing vignette — deepen edges/corners so content reads as spotlit. */
.u-vignette { box-shadow: inset 0 0 150px 44px rgba(9, 9, 13, 0.5); }

/* Broad radial gold glow (place + size with inline style per section). */
.u-glow-gold {
  background: radial-gradient(circle at center, rgba(211, 148, 7, 0.13), rgba(211, 148, 7, 0) 62%);
  filter: blur(12px);
}

/* ============================================================================
   GHOST FRAME — the gold offset frame behind product/process cards.
   Wrap a card in `.card-mount`; the ::before sits BEHIND it in every state via
   isolation + z-index:-1. Interactive cards deepen the offset on hover (desktop
   only); add `.card-mount--static` to keep it fixed (e.g. The Process images).
   ============================================================================ */
.card-mount { position: relative; isolation: isolate; }
.card-mount::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  border-radius: var(--r-lg);
  border: 1px solid var(--gold-line);
  transform: translate(8px, 8px);
  transition: transform var(--dur) var(--ease-out), border-color var(--dur) ease;
  pointer-events: none;
}
.card-mount--feat::before { border-color: rgba(211, 148, 7, 0.2); }
@media (hover: hover) and (min-width: 880px) {
  .card-mount:not(.card-mount--static):hover::before {
    transform: translate(12px, 12px);
    border-color: var(--gold-line-hover);
  }
}

/* ============================================================================
   GOLD BUTTON — canonical CTA with the origin-fill ripple (a dark circle grows
   from the pointer/tap point; the label flips to white). The ripple geometry is
   driven by JS (assets/js/gold-button.js); this is the static shell + fallback.
   ============================================================================ */
.btn-gold {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  background: var(--gold);
  color: var(--gold-ink);
  border: none;
  border-radius: var(--r-pill);
  font-weight: 700;
  font-size: 15px;
  padding: 16px 32px;
  min-height: 52px;
  text-decoration: none;
  cursor: pointer;
}
.btn-gold__fill {
  position: absolute;
  z-index: 1;
  top: 0; left: 0;
  width: 0; height: 0;
  border-radius: 50%;
  background: var(--gold-ink);
  transform: translate(-50%, -50%) scale(0);
  transition: transform 0.52s var(--ease-inout);
  pointer-events: none;
  will-change: transform;
}
.btn-gold__label {
  position: relative;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  color: var(--gold-ink);
  transition: color 0.45s ease;
}
/* Fallback for no-JS: a simple invert on hover. */
@media (hover: hover) {
  .no-js .btn-gold:hover { filter: brightness(1.04); }
}

/* Outline-gold button (inverts to solid gold on hover) — e.g. "View All". */
.btn-outline-gold {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  border: 1px solid var(--gold);
  color: var(--gold);
  background: transparent;
  border-radius: var(--r-pill);
  font-weight: 700;
  font-size: 15px;
  padding: 16px 44px;
  min-height: 52px;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--dur-fast) ease, color var(--dur-fast) ease;
}
@media (hover: hover) {
  .btn-outline-gold:hover { background: var(--gold); color: var(--gold-ink); }
}

/* ---- Scroll reveal (JS adds .is-in) ---- */
.reveal {
  opacity: 0;
  transform: translateY(30px);
  transition: opacity 0.9s var(--ease-out), transform 0.9s var(--ease-out);
}
.reveal.is-in { opacity: 1; transform: none; }

/* ---- Layout helpers ---- */
.wrap { max-width: var(--wrap); margin-inline: auto; }
.wrap-narrow { max-width: var(--wrap-narrow); margin-inline: auto; }
