/*
  ============================================================================
  SYSTEM.CSS — visual system for the PhotoPacks.ai open-source rival
  ============================================================================
  Built for 8 landing pages with very different voices (job seeker, C-level
  executive, Gen-Z) that must read as a family, never as clones.

  Structure:
    1. Font imports (Google Fonts only)
    2. Tokens — light (:root), dark overrides (media + [data-theme])
    3. Reset
    4. Layout primitives (container, section, grid)
    5. Typography classes
    6. Components: eyebrow, badge, buttons, hero, proof grid + credential
       ring, price card, FAQ, testimonial strip
    7. Motion (keyframes) + prefers-reduced-motion guard
    8. Utilities

  See REFERENCES.md for what was taken from photopacks.ai and photoshot
  (premieroctet), with the exact CSS rule quoted, and what was rejected.

  ATTRIBUTION — geometry & motion tokens from Astryx
  Radius, spacing (up to 3rem), border width, easing and elevation values
  below are sourced from Astryx (github.com/facebook/astryx), packages
  @astryxdesign/theme-neutral and @astryxdesign/core, v0.5.1.
  Copyright (c) 2026 Meta Platforms, Inc. Licensed under the MIT License.
  Our own token names are kept; Astryx's raw tokens are defined alongside
  them as the source (see "ASTRYX SOURCE TOKENS" below) so the mapping is
  traceable both in this file and in styleguide.html. Astryx's color scale
  is NOT imported — every color in this file is still ours. .marquee and
  .proof-grid are frozen and untouched; see REFERENCES.md for why.
  ============================================================================
*/

@import url('https://fonts.googleapis.com/css2?family=Bricolage+Grotesque:opsz,wght@12..96,200..800&family=Public+Sans:wght@400;500;600;700;800&family=IBM+Plex+Mono:wght@400;500;600&display=swap');

/* ==========================================================================
   1. TOKENS — LIGHT (default)
   ========================================================================== */
:root {
  /* ---- Color: surfaces & ink ------------------------------------------ */
  /* True white, as directed. --paper-sunk is a barely-violet-tinted white
     used to separate sections without ever leaving "white". */
  --paper: #ffffff;
  --paper-sunk: #faf8fb;
  --paper-raised: #ffffff;

  --ink: #16131c;
  --ink-soft: #4b4553;
  --ink-faint: #6f6879;

  --line: #e6e1ec;
  --line-strong: #cec5da;

  /* ---- Color: the Instagram-derived accent trio -------------------------
     Source hues (real Instagram brand gradient): #FEDA75 → #FA7E1E →
     #D62976 → #962FBF → #4F5BD5. We keep three stops from the middle of
     that run — amber, magenta, violet — and deepen/desaturate each by
     roughly 15-20% so they read as pigment on paper, not as app-icon
     plastic. This trio NEVER fills a background block; see components
     below for where it is allowed to appear. */
  --amber: #c9822a;
  --magenta: #a82f68;
  --violet: #5b3a88;

  --amber-tint: #f6e9d4;
  --magenta-tint: #f3dde8;
  --violet-tint: #e6dbf1;

  --gradient-brand: linear-gradient(115deg, var(--amber) 0%, var(--magenta) 55%, var(--violet) 100%);
  --gradient-ring: conic-gradient(from 210deg, var(--amber), var(--magenta), var(--violet), var(--amber));
  --gradient-glow: radial-gradient(circle at 30% 20%, color-mix(in srgb, var(--magenta) 35%, transparent), transparent 60%),
                   radial-gradient(circle at 75% 75%, color-mix(in srgb, var(--amber) 30%, transparent), transparent 55%);

  /* ---- Color: neutral scale, violet-tinted (never flat gray) ---------- */
  --gray-50: #f7f5f9;
  --gray-100: #eeebf2;
  --gray-200: #ddd7e5;
  --gray-300: #c4bccf;
  --gray-500: #948c9e;
  --gray-700: #554e5f;
  --gray-900: #221d28;

  /* ---- Color: semantic ---------------------------------------------- */
  --focus-ring: #5b3a88;
  --success: #2f7a52;

  /* ---- Typography ------------------------------------------------------
     Three roles, none of them Inter or Space Grotesk:
     - Bricolage Grotesque: expressive at display sizes, used sparingly.
     - Public Sans: the workhorse body face — built for government-grade
       accessibility, which fits a system that must serve a job-seeker
       and a CEO with the same paragraph text.
     - IBM Plex Mono: the "data" voice — prices, badge codes, eyebrows,
       captions. Reads as a credential/manifest, not a UI afterthought. */
  --font-display: 'Bricolage Grotesque', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --font-body: 'Public Sans', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, 'Liberation Mono', monospace;

  --text-xs: 0.75rem;
  --text-sm: 0.875rem;
  --text-base: 1rem;
  --text-md: 1.125rem;
  --text-lg: 1.375rem;
  --text-xl: 1.75rem;
  --text-2xl: 2.25rem;
  --text-3xl: 3rem;
  --text-4xl: 3.75rem;
  --text-5xl: 4.75rem;

  --leading-tight: 1.05;
  --leading-snug: 1.25;
  --leading-normal: 1.55;

  --tracking-tight: -0.025em;
  --tracking-normal: 0em;
  --tracking-wide: 0.08em;
  --tracking-widest: 0.14em;

  /* ---- Astryx source tokens ---------------------------------------------
     Raw values, kept under their own Astryx names, that everything below
     (--radius-*, --space-1..7, --border-width, --dur-*, --ease-standard,
     --shadow-sm/md/lg) sources from instead of carrying its own literal.
     Radius/duration come from @astryxdesign/theme-neutral, which overrides
     them per-theme; spacing, border width and the easing curve come from
     @astryxdesign/core, which the neutral theme does not redefine. See the
     attribution note at the top of this file. No color lives here. */
  --radius-none: 0px;
  --radius-inner: 0.375rem;    /* 6px */
  --radius-element: 0.625rem;  /* 10px */
  --radius-container: 0.75rem; /* 12px */
  --radius-page: 1.75rem;      /* 28px */
  --radius-full: 9999px;

  --spacing-1: 0.25rem;  /* 4px */
  --spacing-2: 0.5rem;   /* 8px */
  --spacing-3: 0.75rem;  /* 12px */
  --spacing-4: 1rem;     /* 16px */
  --spacing-6: 1.5rem;   /* 24px */
  --spacing-8: 2rem;     /* 32px */
  --spacing-12: 3rem;    /* 48px */

  --duration-fast: 125ms;
  --duration-medium: 300ms;
  --duration-slow: 700ms;

  /* Astryx's own semantic padding tokens. Exposed for reference/attribution
     and shown in the styleguide, but NOT wired into .price-card or
     .section: our macro spacing (--space-6 / --space-9, 32-96px) already
     does that job at a scale this 12px component-level token doesn't
     cover — wiring it in would shrink padding no one asked to change. */
  --astryx-card-padding: var(--spacing-3);
  --astryx-section-padding: var(--spacing-3);

  /* ---- Spacing (4px base) ----------------------------------------------
     --space-1..7 source Astryx's spacing scale — exact px matches up to
     48px (4/8/12/16/24/32/48). Astryx's scale stops at --spacing-12 (48px):
     it's a component micro-spacing scale, not a page-layout one, so
     --space-8/9/10 (64/96/128px, hero and section padding) stay our own
     literals — nothing in Astryx claims that range. */
  --space-1: var(--spacing-1, 0.25rem);
  --space-2: var(--spacing-2, 0.5rem);
  --space-3: var(--spacing-3, 0.75rem);
  --space-4: var(--spacing-4, 1rem);
  --space-5: var(--spacing-6, 1.5rem);
  --space-6: var(--spacing-8, 2rem);
  --space-7: var(--spacing-12, 3rem);
  --space-8: 4rem;
  --space-9: 6rem;
  --space-10: 8rem;

  /* ---- Radius -------------------------------------------------------
     Progression replaced with Astryx's radius scale (inner → element →
     container → page → full). sm/md land on the same numbers Astryx uses
     (6px/10px) — kept as var() sourcing anyway for traceability. lg/xl
     genuinely change: 1rem → 0.75rem and 1.5rem → 1.75rem. */
  --radius-sm: var(--radius-inner, 0.375rem);
  --radius-md: var(--radius-element, 0.625rem);
  --radius-lg: var(--radius-container, 0.75rem);
  --radius-xl: var(--radius-page, 1.75rem);
  --radius-pill: var(--radius-full, 9999px);

  /* Astryx core token of the same name (border-width: 1px) — we already
     used a bare 1px literal everywhere; this just gives it a name and a
     documented source. */
  --border-width: 1px;

  /* ---- Shadow --------------------------------------------------------
     Geometry replaced with Astryx's shadow-low/med/high (offsets, blur,
     two-layer opacity steps 5%/10%, 5%/10%, 10%/15%). The color stays
     ours — var(--ink), never Astryx's palette — the same substitution
     principle as everywhere else in this pass. --shadow-glow is untouched:
     Astryx has no "colored ambient glow" shadow to source from; it stays
     the photoshot-derived signature described in REFERENCES.md. */
  --shadow-sm: 0 2px 4px color-mix(in srgb, var(--ink) 5%, transparent), 0 4px 8px color-mix(in srgb, var(--ink) 10%, transparent);
  --shadow-md: 0 2px 4px color-mix(in srgb, var(--ink) 5%, transparent), 0 4px 12px color-mix(in srgb, var(--ink) 10%, transparent);
  --shadow-lg: 0 4px 6px color-mix(in srgb, var(--ink) 10%, transparent), 0 12px 24px color-mix(in srgb, var(--ink) 15%, transparent);
  --shadow-glow: 0 20px 60px -12px color-mix(in srgb, var(--magenta) 45%, transparent),
                 0 8px 24px -8px color-mix(in srgb, var(--violet) 35%, transparent);

  /* ---- Motion ----------------------------------------------------------
     --ease-signature is lifted verbatim from photopacks.ai's own custom
     easing (not a Tailwind default): cubic-bezier(.87,0,.13,1) — a
     steep, symmetric, "snap" curve. Used for anything that toggles
     state (FAQ disclosure, hover reveals). Astryx has only one easing
     token (--ease-standard) and no alternate "snap" curve, so this one
     stays as-is — nothing to source from Astryx here.
     --ease-standard's curve is replaced with Astryx core's own token of
     the same name: cubic-bezier(0.24,1,0.4,1) — gentler start, sharper
     settle than the previous generic Material curve.
     --dur-fast/base/slow now source Astryx's fast/medium/slow steps
     (theme-neutral: 125/300/700ms). --dur-idle (6s, the .idle-float
     breathing loop) has no Astryx counterpart and stays ours. */
  --ease-signature: cubic-bezier(0.87, 0, 0.13, 1);
  --ease-standard: cubic-bezier(0.24, 1, 0.4, 1);
  --dur-fast: var(--duration-fast, 125ms);
  --dur-base: var(--duration-medium, 300ms);
  --dur-slow: var(--duration-slow, 700ms);
  --dur-idle: 6s;
}

/* ==========================================================================
   1b. TOKENS — DARK
   Redefined under both a system-preference guard and an explicit
   [data-theme="dark"] override, per spec. No color is defined only here.
   ========================================================================== */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper: #15121c;
    --paper-sunk: #1b1725;
    --paper-raised: #201b2a;

    --ink: #f4f1f8;
    --ink-soft: #cbc3d6;
    --ink-faint: #978fa5;

    --line: #332d40;
    --line-strong: #453c55;

    --amber: #e6a94f;
    --magenta: #dd6b9c;
    --violet: #9b74cf;

    --amber-tint: rgba(230, 169, 79, 0.14);
    --magenta-tint: rgba(221, 107, 156, 0.14);
    --violet-tint: rgba(155, 116, 207, 0.16);

    --gray-50: #201b2a;
    --gray-100: #282232;
    --gray-200: #362f42;
    --gray-300: #4a4157;
    --gray-500: #8a8296;
    --gray-700: #c4bdcf;
    --gray-900: #f4f1f8;

    --focus-ring: #b895e6;

    /* Same Astryx shadow-low/med/high geometry as :root, at the heavier
       opacity steps (25/40, 35/50, 50/70%) Astryx's own dark values use,
       plus the inset edge-ring Astryx adds only in dark mode — a subtle
       highlight that defines a raised surface's top edge on a dark
       background. Ring color is ours (--ink-soft), not Astryx's. */
    --shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.25), 0 4px 8px rgba(0, 0, 0, 0.4), inset 0 0 0 1px color-mix(in srgb, var(--ink-soft) 8%, transparent);
    --shadow-md: 0 2px 4px rgba(0, 0, 0, 0.35), 0 4px 12px rgba(0, 0, 0, 0.5), inset 0 0 0 1px color-mix(in srgb, var(--ink-soft) 12%, transparent);
    --shadow-lg: 0 4px 6px rgba(0, 0, 0, 0.5), 0 12px 24px rgba(0, 0, 0, 0.7), inset 0 0 0 1px color-mix(in srgb, var(--ink-soft) 15%, transparent);
    --shadow-glow: 0 20px 60px -10px color-mix(in srgb, var(--magenta) 40%, transparent),
                   0 8px 24px -6px color-mix(in srgb, var(--violet) 32%, transparent);
  }
}

:root[data-theme="dark"] {
  --paper: #15121c;
  --paper-sunk: #1b1725;
  --paper-raised: #201b2a;

  --ink: #f4f1f8;
  --ink-soft: #cbc3d6;
  --ink-faint: #978fa5;

  --line: #332d40;
  --line-strong: #453c55;

  --amber: #e6a94f;
  --magenta: #dd6b9c;
  --violet: #9b74cf;

  --amber-tint: rgba(230, 169, 79, 0.14);
  --magenta-tint: rgba(221, 107, 156, 0.14);
  --violet-tint: rgba(155, 116, 207, 0.16);

  --gray-50: #201b2a;
  --gray-100: #282232;
  --gray-200: #362f42;
  --gray-300: #4a4157;
  --gray-500: #8a8296;
  --gray-700: #c4bdcf;
  --gray-900: #f4f1f8;

  --focus-ring: #b895e6;

  /* Same Astryx shadow-low/med/high geometry as :root, at the heavier
     opacity steps (25/40, 35/50, 50/70%) Astryx's own dark values use,
     plus the inset edge-ring Astryx adds only in dark mode — a subtle
     highlight that defines a raised surface's top edge on a dark
     background. Ring color is ours (--ink-soft), not Astryx's. */
  --shadow-sm: 0 2px 4px rgba(0, 0, 0, 0.25), 0 4px 8px rgba(0, 0, 0, 0.4), inset 0 0 0 1px color-mix(in srgb, var(--ink-soft) 8%, transparent);
  --shadow-md: 0 2px 4px rgba(0, 0, 0, 0.35), 0 4px 12px rgba(0, 0, 0, 0.5), inset 0 0 0 1px color-mix(in srgb, var(--ink-soft) 12%, transparent);
  --shadow-lg: 0 4px 6px rgba(0, 0, 0, 0.5), 0 12px 24px rgba(0, 0, 0, 0.7), inset 0 0 0 1px color-mix(in srgb, var(--ink-soft) 15%, transparent);
  --shadow-glow: 0 20px 60px -10px color-mix(in srgb, var(--magenta) 40%, transparent),
                 0 8px 24px -6px color-mix(in srgb, var(--violet) 32%, transparent);
}

/* ==========================================================================
   2. RESET
   ========================================================================== */
*,
*::before,
*::after {
  box-sizing: border-box;
}

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

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: var(--leading-normal);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img,
svg,
video {
  max-width: 100%;
  display: block;
}

a {
  color: inherit;
}

button {
  font: inherit;
  color: inherit;
}

ul,
ol {
  padding: 0;
  margin: 0;
  list-style: none;
}

h1, h2, h3, h4, p, figure, blockquote {
  margin: 0;
}

:focus-visible {
  outline: 2px solid var(--focus-ring);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ==========================================================================
   3. LAYOUT PRIMITIVES
   ========================================================================== */
.container {
  width: 100%;
  max-width: 74rem;
  margin-inline: auto;
  padding-inline: var(--space-5);
}

.section {
  padding-block: var(--space-9);
  background: var(--paper);
}

.section--sunk {
  background: var(--paper-sunk);
}

.section--tight {
  padding-block: var(--space-7);
}

.stack > * + * {
  margin-top: var(--space-5);
}

.cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-3);
}

/* ==========================================================================
   4. TYPOGRAPHY
   ========================================================================== */
.display-1,
.display-2,
.display-3 {
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: var(--tracking-tight);
  line-height: var(--leading-tight);
  color: var(--ink);
  /* A display face at 44px meets words longer than a 390px phone column, and
     an unbreakable word pushes the whole document sideways — the one defect
     that makes a landing page feel broken on the device most of this traffic
     arrives on. The clamp minimum below is the aesthetic fix; this is the
     guarantee, because no minimum survives a long enough word. */
  overflow-wrap: break-word;
  hyphens: auto;
}

.display-1 {
  font-size: clamp(2.1rem, 1.5rem + 3.4vw, var(--text-5xl));
}

.display-2 {
  font-size: clamp(2.1rem, 1.7rem + 1.8vw, var(--text-3xl));
}

.display-3 {
  font-size: clamp(1.5rem, 1.3rem + 0.9vw, var(--text-xl));
}

.lede {
  font-family: var(--font-body);
  font-size: var(--text-md);
  font-weight: 400;
  color: var(--ink-soft);
  line-height: var(--leading-normal);
  max-width: 40rem;
}

.body-text {
  font-family: var(--font-body);
  font-size: var(--text-base);
  color: var(--ink-soft);
}

.mono-label {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
}

/* Gradient text fill — reserved for a single numeral or word per page.
   This is one of the three sanctioned uses of --gradient-brand. */
.text-brand-fill {
  background: var(--gradient-brand);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

/* ==========================================================================
   5. COMPONENTS
   ========================================================================== */

/* ---- Eyebrow (occhiello) -------------------------------------------- */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: var(--tracking-widest);
  text-transform: uppercase;
  color: var(--ink-soft);
}

.eyebrow::before {
  content: "";
  width: 1.25rem;
  height: 2px;
  border-radius: var(--radius-pill);
  background: var(--gradient-brand);
  flex-shrink: 0;
}

/* ---- Badge ------------------------------------------------------------
   A small pill. .badge--credential wears the thin gradient ring — the
   system's signature mark of "verified" status. */
.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--radius-pill);
  background: var(--gray-50);
  border: var(--border-width) solid var(--line);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: 500;
  letter-spacing: var(--tracking-wide);
  color: var(--ink-soft);
}

.badge--credential {
  position: relative;
  background: var(--paper);
  border: none;
  padding: calc(var(--space-1) + 1px) calc(var(--space-3) + 1px);
}

.badge--credential::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1.5px;
  background: var(--gradient-ring);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}

/* ---- Buttons ------------------------------------------------------------
   Primary is a solid ink fill — deliberately NOT gradient-filled, to keep
   the accent trio rare. The gradient only shows as a 2px underlayer that
   peeks out on hover/focus, like a credential catching light. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: 0.85rem 1.5rem;
  border-radius: var(--radius-md);
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--text-sm);
  letter-spacing: 0.01em;
  cursor: pointer;
  border: var(--border-width) solid transparent;
  transition: transform var(--dur-fast) var(--ease-standard),
    box-shadow var(--dur-base) var(--ease-standard),
    background var(--dur-base) var(--ease-standard);
}

.btn:active {
  transform: translateY(1px);
}

.btn-primary {
  position: relative;
  background: var(--ink);
  color: var(--paper);
  isolation: isolate;
}

.btn-primary::before {
  content: "";
  position: absolute;
  inset: -2px;
  z-index: -1;
  border-radius: calc(var(--radius-md) + 2px);
  background: var(--gradient-brand);
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-standard);
}

.btn-primary:hover::before,
.btn-primary:focus-visible::before {
  opacity: 1;
}

.btn-primary .btn-arrow {
  transition: transform var(--dur-base) var(--ease-standard);
}

.btn-primary:hover .btn-arrow {
  transform: translateX(4px);
}

.btn-secondary {
  background: transparent;
  color: var(--ink);
  border-color: var(--line-strong);
}

.btn-secondary:hover {
  border-color: var(--ink);
  background: var(--gray-50);
}

/* ---- Hero --------------------------------------------------------------- */
.hero {
  position: relative;
  padding-block: var(--space-10) var(--space-9);
  overflow: hidden;
}

.hero__glow {
  position: absolute;
  inset: -20% -10% auto -10%;
  height: 32rem;
  background: var(--gradient-glow);
  opacity: 0.5;
  filter: blur(40px);
  pointer-events: none;
  z-index: 0;
}

.hero__content {
  position: relative;
  z-index: 1;
  display: grid;
  gap: var(--space-6);
  max-width: 46rem;
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-top: var(--space-2);
}

/* ---- Proof grid + credential ring ---------------------------------------
   The signature element: a thin conic-gradient ring, a direct but
   restrained nod to Instagram's story ring, reinterpreted here as a mark
   of a verified/finished credential photo rather than "new content". */
.proof-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
  gap: var(--space-4);
}

.proof-item {
  aspect-ratio: 4 / 5;
  /* FROZEN: 1rem is what --radius-lg used to resolve to before the Astryx
     graft (now 0.75rem). .proof-grid is approved as-is and must not shift
     even indirectly — literal value on purpose, do not swap back to
     var(--radius-lg). */
  border-radius: 1rem;
  overflow: hidden;
  background: var(--gray-100);
  position: relative;
}

.proof-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  filter: brightness(1);
  /* FROZEN: literal durations/easing, equal to what --dur-base/--dur-slow/
     --ease-standard used to resolve to before the Astryx graft (250ms/450ms,
     cubic-bezier(0.4,0,0.2,1)). Same reasoning as the radius above — this
     hover timing is part of the approved .proof-grid, not to be re-linked. */
  transition: filter 250ms cubic-bezier(0.4, 0, 0.2, 1),
    transform 450ms cubic-bezier(0.4, 0, 0.2, 1);
}

.proof-item:hover img {
  filter: brightness(1.06);
  transform: scale(1.03);
}

.credential-ring {
  position: relative;
  border-radius: 50%;
  padding: 2px;
  background: var(--gradient-ring);
  display: inline-flex;
  flex-shrink: 0;
}

.credential-ring img {
  border-radius: 50%;
  border: 2px solid var(--paper);
  display: block;
}

.credential-ring--sm {
  padding: 1.5px;
}

/* ---- Price card ----------------------------------------------------- */
.price-card {
  border: var(--border-width) solid var(--line);
  border-radius: var(--radius-xl);
  padding: var(--space-6);
  background: var(--paper-raised);
  display: grid;
  gap: var(--space-4);
  transition: border-color var(--dur-base) var(--ease-standard),
    box-shadow var(--dur-base) var(--ease-standard);
}

.price-card:hover {
  box-shadow: var(--shadow-md);
}

.price-card--featured {
  position: relative;
  border-color: transparent;
  box-shadow: var(--shadow-glow);
}

.price-card--featured::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  padding: 1.5px;
  background: var(--gradient-ring);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}

.price-card__amount {
  font-family: var(--font-mono);
  font-size: var(--text-3xl);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  letter-spacing: var(--tracking-tight);
  color: var(--ink);
}

.price-card__period {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--ink-faint);
}

.price-card__list {
  display: grid;
  gap: var(--space-3);
}

.price-card__list li {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--ink-soft);
}

.price-card__list li::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--gradient-brand);
  flex-shrink: 0;
  transform: translateY(-2px);
}

/* ---- FAQ ------------------------------------------------------------- */
.faq {
  border-top: var(--border-width) solid var(--line);
}

.faq-item {
  border-bottom: var(--border-width) solid var(--line);
}

.faq-item__q {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding-block: var(--space-5);
  background: none;
  border: none;
  text-align: left;
  cursor: pointer;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-md);
  color: var(--ink);
}

.faq-item__icon {
  flex-shrink: 0;
  width: 1.5rem;
  height: 1.5rem;
  position: relative;
}

.faq-item__icon::before,
.faq-item__icon::after {
  content: "";
  position: absolute;
  background: var(--ink);
  border-radius: var(--radius-pill);
}

.faq-item__icon::before {
  inset: 47% 0;
  height: 2px;
}

.faq-item__icon::after {
  inset: 0 47%;
  width: 2px;
  transition: transform var(--dur-base) var(--ease-signature);
}

.faq-item[open] .faq-item__icon::after {
  transform: rotate(90deg);
}

.faq-item summary {
  list-style: none;
}

.faq-item summary::-webkit-details-marker {
  display: none;
}

.faq-item__a {
  padding-bottom: var(--space-5);
  padding-right: var(--space-8);
  color: var(--ink-soft);
  font-size: var(--text-base);
  line-height: var(--leading-normal);
}

/* ---- Testimonial strip --------------------------------------------- */
.testimonial-strip {
  display: flex;
  gap: var(--space-5);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-bottom: var(--space-3);
  scrollbar-width: thin;
}

.testimonial-card {
  scroll-snap-align: start;
  flex: 0 0 min(20rem, 85vw);
  border: var(--border-width) solid var(--line);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  background: var(--paper-raised);
  display: grid;
  gap: var(--space-4);
}

.testimonial-card__quote {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--text-md);
  line-height: var(--leading-snug);
  letter-spacing: var(--tracking-tight);
  color: var(--ink);
}

.testimonial-card__person {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.testimonial-card__meta {
  display: grid;
  gap: 2px;
}

.testimonial-card__name {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--ink);
}

.testimonial-card__role {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--ink-faint);
}

/* ==========================================================================
   6. MOTION
   ========================================================================== */
@keyframes float-in {
  from {
    opacity: 0;
    transform: translateY(24px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes breathe {
  0%, 100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-10px);
  }
}

@keyframes shimmer {
  0% {
    background-position: -200% 0;
  }
  100% {
    background-position: 200% 0;
  }
}

@keyframes marquee-scroll {
  from {
    transform: translateY(0);
  }
  to {
    transform: translateY(-50%);
  }
}

.reveal {
  animation: float-in var(--dur-slow) var(--ease-standard) both;
}

.reveal--delay-1 { animation-delay: 90ms; }
.reveal--delay-2 { animation-delay: 180ms; }
.reveal--delay-3 { animation-delay: 270ms; }

.idle-float {
  animation: breathe 6s var(--ease-standard) infinite;
}

.skeleton {
  background: linear-gradient(90deg, var(--gray-100) 25%, var(--gray-50) 50%, var(--gray-100) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.6s linear infinite;
}

/* Vertical, seamlessly-looping proof wall — steal from photopacks.ai's
   swipeUp keyframe, generalized to a % transform so any track height
   works via duplicated content. Opt-in, decorative only. */
.marquee {
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 8%, #000 92%, transparent);
  mask-image: linear-gradient(to bottom, transparent, #000 8%, #000 92%, transparent);
}

.marquee__track {
  display: grid;
  gap: var(--space-4);
  animation: marquee-scroll 40s linear infinite;
}

@media (prefers-reduced-motion: reduce) {
  .reveal,
  .idle-float,
  .skeleton,
  .marquee__track {
    animation: none !important;
  }
  .reveal {
    opacity: 1;
    transform: none;
  }
  * {
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ==========================================================================
   7. UTILITIES
   ========================================================================== */
.text-center { text-align: center; }
.mx-auto { margin-inline: auto; }
.flow-tight > * + * { margin-top: var(--space-3); }

.grid-2 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));
  gap: var(--space-6);
}

.grid-3 {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: var(--space-5);
}
