/* ============================================================================
   Exchanging Lore -- shared motion system (Phase 1)

   Centralizes the site's existing motion vocabulary (cubic-bezier(0.22,1,0.36,1)
   is already used pervasively across every page's own inline <style> block)
   into named tokens, and adds new sitewide behavior: nav scroll state, a top
   scroll-progress bar, a full-screen accessible mobile menu overlay, a premium
   button system, and hero decorative layers.

   Loaded LAST in <head>, after each page's own inline <style> block, so equal-
   specificity rules here can extend/override the legacy inline rules without
   !important. Every new transition/animation has a matching
   prefers-reduced-motion override. See assets/js/motion-system.js for the
   behavior that drives these classes/attributes.
   ============================================================================ */

:root {
  /* Durations */
  --motion-micro: 200ms;      /* 150-250ms: focus rings, icon swaps, small toggles */
  --motion-control: 320ms;    /* 250-400ms: buttons, cards -- matches existing .btn/.card duration */
  --motion-reveal: 650ms;     /* 500-800ms: section reveals (reserved; .reveal itself is untouched) */
  --motion-page: 400ms;       /* 300-500ms: full-screen mobile nav, future page transitions */

  /* Easing -- reuse the site's existing curve, don't invent a new one */
  --motion-ease: cubic-bezier(0.22, 1, 0.36, 1);

  /* Motion distances */
  --motion-dist-sm: 8px;
  --motion-dist-md: 16px;

  /* Stagger */
  --motion-stagger-step: 90ms;

  /* Magnetic button bounds -- "a few px max" */
  --magnet-max: 7px;

  /* Runtime-measured by JS; static fallback for first paint */
  --header-height: 88px;

  /* Runtime-updated by JS */
  --scroll-progress: 0;
  --mx: 50%;
  --my: 30%;
}

@media (prefers-reduced-motion: reduce) {
  :root {
    --motion-micro: 1ms;
    --motion-control: 1ms;
    --motion-reveal: 1ms;
    --motion-page: 1ms;
    --motion-stagger-step: 0ms;
  }
}

/* ===== Nav scroll state ===================================================
   ID-anchored selector deliberately: Tailwind's CDN runtime injects its
   generated stylesheet at a non-deterministic point relative to this static
   <link>, so a class-only rule can't reliably beat a Tailwind utility class.
   Targets the header's direct child wrapper (already `.max-w-7xl ... py-4
   sm:py-5 lg:py-6` on every page) rather than editing those Tailwind classes. */
#site-header {
  transition: background-color var(--motion-control) var(--motion-ease),
              box-shadow var(--motion-control) var(--motion-ease);
}
#site-header > .max-w-7xl {
  transition: padding var(--motion-control) var(--motion-ease);
}
#site-header[data-scrolled="true"] {
  background-color: rgb(var(--background-rgb) / 0.75);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  box-shadow: 0 1px 0 var(--border), 0 12px 30px -18px rgb(var(--foreground-rgb) / 0.25);
}
#site-header[data-scrolled="true"] > .max-w-7xl {
  padding-top: 0.85rem;
  padding-bottom: 0.85rem;
}
@media (min-width: 640px) {
  #site-header[data-scrolled="true"] > .max-w-7xl { padding-top: 0.9rem; padding-bottom: 0.9rem; }
}
@media (min-width: 1024px) {
  #site-header[data-scrolled="true"] > .max-w-7xl { padding-top: 1rem; padding-bottom: 1rem; }
}
@media (prefers-reduced-motion: reduce) {
  #site-header, #site-header > .max-w-7xl { transition: none; }
}

/* Current in-page section highlight, applied to the existing .nav-link */
.nav-link.is-current::after { transform: scaleX(1); transform-origin: left; }
.nav-link.is-current { color: var(--foreground); }

/* ===== Scroll progress bar =================================================
   First child inside #site-header -- inherits the header's existing z-50
   stacking context, no new z-index needed. */
#scroll-progress {
  position: absolute;
  left: 0;
  bottom: -1px;
  height: 2px;
  width: 100%;
  background: var(--accent);
  transform: scaleX(var(--scroll-progress, 0));
  transform-origin: left;
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  #scroll-progress { transition: none; }
}

/* ===== Full-screen mobile menu overlay =====================================
   The old per-page setMenu() sets an INLINE style.maxHeight, which no external
   stylesheet can override -- see the per-page checklist edit that changes it
   to '100vh' so this overlay has room to render into. */
@media (max-width: 1023.98px) {
  /* "Rolling down" reveal: clip-path (not height) so the panel unrolls from
     the header edge without triggering layout, keeping this compositor-only
     -- animating height/max-height here would reflow the whole page on every
     frame. clip-path's own duration runs a little longer than the standard
     control timing so the roll reads as a deliberate motion, not a snap. */
  #mobile-menu.is-open {
    position: fixed;
    top: var(--header-height);
    left: 0;
    right: 0;
    bottom: 0;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding-bottom: env(safe-area-inset-bottom, 0);
    opacity: 0;
    clip-path: inset(0 0 100% 0);
    transition: opacity var(--motion-control) var(--motion-ease),
                clip-path 480ms var(--motion-ease);
  }
  #mobile-menu.is-open.is-visible {
    opacity: 1;
    clip-path: inset(0 0 0% 0);
  }
  #mobile-menu.is-open .mobile-link {
    opacity: 0;
    transform: translateY(10px);
    transition: opacity var(--motion-control) var(--motion-ease),
                transform var(--motion-control) var(--motion-ease);
    transition-delay: calc(var(--i, 0) * var(--motion-stagger-step) + 90ms);
  }
  #mobile-menu.is-open.is-visible .mobile-link {
    opacity: 1;
    transform: translateY(0);
  }
}

/* #site-header's Tailwind `backdrop-blur` class establishes a new containing
   block for position:fixed descendants (backdrop-filter behaves like filter
   here per spec, in every current engine -- not just old WebKit). #mobile-menu
   lives inside <header>, so without this override its "fixed" full-screen
   overlay resolves against the ~88px header box instead of the viewport,
   collapsing it to ~1px tall. Confirmed via computed-style diagnosis on the
   live site. Backdrop blur disappearing for the ~320ms the menu is open is
   imperceptible -- the menu covers the header anyway once visible. */
html.is-menu-open #site-header {
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
@media (prefers-reduced-motion: reduce) {
  #mobile-menu.is-open,
  #mobile-menu.is-open .mobile-link {
    transition: none !important;
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
  }
}

/* Body scroll-lock helper applied by JS while the mobile menu is open */
html.is-menu-open {
  overflow: hidden;
}
body.is-menu-locked {
  position: fixed;
  left: 0;
  right: 0;
  width: 100%;
}

/* ===== Base button system ===================================================
   Canonical definitions, consolidated here from what used to be 11 separate
   near-identical copies pasted into each page's own inline <style> block.
   That drifted in real ways -- .btn-on-inverse's hover color was literally
   inverted between lore-and-form.html and payments.html, and several pages
   were simply missing variants (.btn-outline-light, .btn-solid-light,
   .btn-ghost) that others had. One definition, used everywhere, extended by
   the additive "Premium button system" layer just below. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.55rem;
  min-height: 50px; padding: 0 1.85rem; border-radius: 4px;
  font-family: 'Inter', sans-serif; font-weight: 600; font-size: 0.82rem;
  letter-spacing: 0.08em; text-transform: uppercase;
  transition-property: transform, opacity, box-shadow, background-color, border-color, color;
  transition-duration: 280ms;
  transition-timing-function: cubic-bezier(0.22,1,0.36,1);
}
.btn-primary { background: var(--foreground); color: var(--background); }
.btn-primary:hover { background: var(--accent); color: var(--on-accent); transform: translateY(-2px); box-shadow: 0 14px 30px -12px rgb(var(--accent-rgb) / 0.55); }
.btn-primary:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.btn-outline { background: transparent; color: var(--foreground); border: 1px solid var(--border-strong); }
.btn-outline:hover { border-color: var(--accent); background: rgb(var(--accent-rgb) / 0.06); transform: translateY(-2px); box-shadow: 0 12px 26px -14px rgb(var(--foreground-rgb) / 0.28); }
.btn-outline:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
/* These two variants exist specifically for "always dark" sections
   (bg-ink text-paper bands -- CTA blocks, footers) that must look the same
   regardless of site theme. They deliberately use the FIXED --paper/--ink
   tokens (see EMAIL_ROUTING.md-era fix to bg-charcoal/text-warm for the
   same root cause) rather than the theme-relative --background/--foreground
   -- those flip with light/dark mode, which would make button text
   invisible (near-black on near-black) the moment a visitor is in dark
   mode, since --background is already dark there too. */
.btn-outline-light { background: transparent; color: var(--paper); border: 1px solid rgb(var(--paper-rgb) / 0.35); }
.btn-outline-light:hover { border-color: var(--accent); color: var(--accent); background: rgb(var(--paper-rgb) / 0.06); transform: translateY(-2px); }
.btn-outline-light:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.btn-solid-light { background: var(--paper); color: var(--ink); }
.btn-solid-light:hover { background: var(--accent); color: var(--on-accent); transform: translateY(-2px); box-shadow: 0 14px 30px -12px rgb(var(--accent-rgb) / 0.5); }
.btn-solid-light:focus-visible { outline: 2px solid var(--paper); outline-offset: 3px; }
.btn-ghost { background: transparent; color: var(--muted); border: 1px solid transparent; }
.btn-ghost:hover { color: var(--foreground); background: rgb(var(--accent-rgb) / 0.06); transform: translateY(-1px); }
.btn-ghost:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.btn-on-inverse { background: var(--accent); color: var(--on-accent); }
.btn-on-inverse:hover { background: var(--background); color: var(--foreground); transform: translateY(-2px); box-shadow: 0 14px 30px -12px rgb(var(--foreground-rgb) / 0.35); }
.btn-on-inverse:focus-visible { outline: 2px solid var(--background); outline-offset: 3px; }

/* ===== Premium button system ===============================================
   Additive only -- no existing .btn rule is overridden, just extended. */
.btn {
  position: relative;
  overflow: hidden;
}
.btn::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(115deg, transparent 20%, rgb(255 255 255 / 0.16) 50%, transparent 80%);
  transform: translateX(-120%);
  transition: transform var(--motion-control) var(--motion-ease);
}
.btn:hover::before,
.btn:active::before {
  transform: translateX(120%);
}
.btn .btn-arrow {
  display: inline-block;
  transition: transform var(--motion-micro) var(--motion-ease);
}
.btn:hover .btn-arrow {
  transform: translateX(3px);
}

/* Border illumination for outline variants -- additive to existing border-color */
.btn-outline, .btn-outline-light {
  box-shadow: 0 0 0 0 rgb(var(--accent-rgb) / 0);
  transition: box-shadow var(--motion-control) var(--motion-ease),
              border-color var(--motion-control) var(--motion-ease),
              background-color var(--motion-control) ease,
              transform var(--motion-control) var(--motion-ease);
}
.btn-outline:hover, .btn-outline-light:hover,
.btn-outline:active, .btn-outline-light:active {
  box-shadow: 0 0 0 1px rgb(var(--accent-rgb) / 0.5);
}

/* Pressed state -- visible even where JS doesn't own transform (magnetic buttons handle their own) */
.btn:active {
  transform: scale(0.97);
}

/* ===== Touch / tap premium polish ==========================================
   Desktop already gets hover, magnetic pull, and the mouse-follow hero light.
   Touch devices get none of those (correctly -- cursor-following effects
   don't translate to touch), so without this block mobile buttons/cards would
   feel flat by comparison. This gives touch its own equally-considered,
   tap-driven feedback instead of a reduced copy of the desktop experience. */
.btn, .card, .work-card, .nav-link, .mobile-link {
  -webkit-tap-highlight-color: transparent;
}
.btn, [data-magnetic], .card, .work-card {
  touch-action: manipulation;
}
.card:active, .work-card:active {
  transform: scale(0.985);
  border-color: rgb(var(--accent-rgb) / 0.45);
}
.mobile-link:active {
  background-color: rgb(var(--accent-rgb) / 0.08);
}
@media (prefers-reduced-motion: reduce) {
  .card:active, .work-card:active { transform: none; }
}

/* Sticky mobile CTA -- clear the iOS home-indicator / gesture area on notched
   devices. Requires viewport-fit=cover on the page's <meta name="viewport">
   (added sitewide) for env() to resolve to a non-zero value; a harmless 0px
   no-op on devices without a safe-area inset. */
#sticky-cta {
  padding-bottom: env(safe-area-inset-bottom, 0);
}

/* Loading / disabled state -- styles whatever assets/js/stripe-checkout.js
   already toggles (aria-busy="true", disabled) without needing JS changes there. */
.btn:disabled,
.btn[aria-busy="true"] {
  opacity: 0.72;
  cursor: progress;
  pointer-events: none;
}
.btn[aria-busy="true"]::after {
  content: '';
  display: inline-block;
  width: 14px;
  height: 14px;
  margin-left: 0.5rem;
  vertical-align: -2px;
  border-radius: 50%;
  border: 2px solid currentColor;
  border-top-color: transparent;
  animation: motion-spin 700ms linear infinite;
}
@keyframes motion-spin {
  to { transform: rotate(360deg); }
}
@media (prefers-reduced-motion: reduce) {
  .btn::before { display: none; }
  .btn .btn-arrow, .btn-outline, .btn-outline-light { transition: none; }
  .btn[aria-busy="true"]::after { animation: none; opacity: 0.6; }
}

/* Magnetic buttons -- JS owns `transform` outright for these via inline style;
   this just documents the contract and ensures a smooth release. */
[data-magnetic] {
  transition: transform 220ms var(--motion-ease);
  will-change: transform;
}
[data-magnetic]:active {
  transition-duration: 90ms;
}

/* ===== Hero decorative layers ==============================================
   Sit at z-index:1, below the hero's existing `relative z-10` content
   wrapper. Never intercept pointer events. */
.hero-marble {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  opacity: 0;
  background-image: url("../brand/png/el-marble-texture.png");
  background-size: cover;
  background-position: center;
}
/* Dark-mode only -- the texture is a black/gold composition, designed for
   the dark theme's near-black background; on light mode it would clash
   rather than read as a refinement. */
@media (prefers-color-scheme: dark) {
  .hero-marble { opacity: 0.22; }
}
.hero-light {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: radial-gradient(480px circle at var(--mx, 50%) var(--my, 30%), rgb(var(--accent-rgb) / 0.10), transparent 65%);
  opacity: 0;
  transition: opacity var(--motion-control) ease;
}
.hero-light.is-active {
  opacity: 1;
}
.hero-grain {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.035;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
@media (prefers-reduced-motion: reduce) {
  .hero-light { display: none; }
}

/* Hero staged entrance -- JS assigns animation-delay inline per [data-hero-step];
   this just ensures elements start from the same hidden state as the existing
   .fade-up animation (defined per-page) before JS runs. */
[data-hero-step] {
  animation-fill-mode: both;
}

/* ===== Hero monogram (inline SVG, replaces the old <picture> PNG) =========
   Inline (not <img src>) specifically so its fills can reference the page's
   own --foreground/--muted/--accent custom properties and auto-follow
   light/dark mode, and so its orbit paths are reachable for a real reveal
   animation instead of a static raster fade-in. */
.hero-monogram {
  display: block;
  width: 100%;
  height: auto;
}
/* Dasharray/dashoffset set to each arc's own path length (main: 230deg at
   r=196 = ~787; top: 80deg at r=196 = ~274) -- must cover the full length or
   the dash pattern repeats mid-arc instead of drawing it in one sweep. */
#hero-orbit-main {
  stroke-dasharray: 790;
  stroke-dashoffset: 790;
  animation: motion-orbit-draw 900ms var(--motion-ease) both;
  animation-delay: 620ms;
}
#hero-orbit-top {
  stroke-dasharray: 280;
  stroke-dashoffset: 280;
  animation: motion-orbit-draw 900ms var(--motion-ease) both;
  animation-delay: 760ms;
}
#hero-orbit-dot {
  opacity: 0;
  animation: motion-fade-in 500ms var(--motion-ease) both;
  animation-delay: 1020ms;
}
.hero-letter-e, .hero-letter-l {
  opacity: 0;
  transform: translateY(6px);
  transform-origin: center;
  animation: motion-letter-in 620ms var(--motion-ease) both;
}
.hero-letter-e { animation-delay: 700ms; }
.hero-letter-l { animation-delay: 780ms; }

/* Light theme keeps flat CSS-variable fills; dark theme swaps to the
   brushed-metal textured letters (clipped image), matching the crest/
   monogram logo files. Both groups carry the same .hero-letter-e/-l classes
   above so the entrance animation applies identically either way. */
.hero-letters-textured {
  display: none;
}
@media (prefers-color-scheme: dark) {
  .hero-letters-flat { display: none; }
  .hero-letters-textured { display: block; }
}

@keyframes motion-orbit-draw {
  to { stroke-dashoffset: 0; }
}
@keyframes motion-fade-in {
  to { opacity: 1; }
}
@keyframes motion-letter-in {
  to { opacity: 1; transform: translateY(0); }
}
@media (prefers-reduced-motion: reduce) {
  #hero-orbit-main, #hero-orbit-top, #hero-orbit-dot, .hero-letter-e, .hero-letter-l {
    animation: none !important;
    stroke-dashoffset: 0 !important;
    opacity: 1 !important;
    transform: none !important;
  }
  .hero-letter-l { opacity: 0.62 !important; }
}

/* ===== Custom cursor (opt-in, desktop only; body flag set by JS) ==========
   Defined here now so later phases can activate it without another CSS
   deploy; inert unless JS adds the class, so this has zero effect in Phase 1. */
body.has-custom-cursor {
  cursor: none;
}
body.has-custom-cursor a,
body.has-custom-cursor button {
  cursor: none;
}
#custom-cursor-dot, #custom-cursor-ring {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 9999;
  pointer-events: none;
  border-radius: 50%;
  transform: translate(-50%, -50%);
}
#custom-cursor-dot {
  width: 6px;
  height: 6px;
  background: var(--accent);
}
#custom-cursor-ring {
  width: 32px;
  height: 32px;
  border: 1px solid rgb(var(--accent-rgb) / 0.5);
  transition: width var(--motion-micro) var(--motion-ease),
              height var(--motion-micro) var(--motion-ease),
              border-color var(--motion-micro) var(--motion-ease);
}

/* ===== Sitewide trust bar =================================================
   Compact row of real capabilities (not client counts/awards -- those are
   never used sitewide). Shared here since it currently only appears on
   index.html but the reassurance-row/tooltip pieces below are reused across
   other pages' forms. */
.trust-bar-list {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 0.85rem 2.25rem;
  padding-top: 1.75rem; margin-top: 1.75rem;
  border-top: 1px solid var(--border);
  list-style: none;
}
.trust-bar-item {
  display: inline-flex; align-items: center; gap: 0.55rem;
  font-size: 0.78rem; font-weight: 600; letter-spacing: 0.01em;
  color: var(--muted);
}
.trust-bar-item svg { width: 16px; height: 16px; color: var(--accent); flex-shrink: 0; }

/* Accessible tooltip -- a real <button> (not a hover-only span) so it works
   identically for mouse, keyboard, and touch. Touch/click toggles
   aria-expanded via JS; hover and focus-visible are handled by CSS alone. */
.trust-tip-trigger {
  position: relative;
  display: inline-flex; align-items: center; gap: 0.55rem;
  background: none; border: none; padding: 0; margin: 0; font-family: inherit; cursor: pointer;
}
.trust-tip-trigger:hover, .trust-tip-trigger:focus-visible { color: var(--foreground); }
.trust-tip-trigger:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; border-radius: 3px; }
.trust-tip {
  position: absolute; left: 50%; bottom: calc(100% + 11px);
  transform: translate(-50%, 4px);
  width: 228px; padding: 0.75rem 0.9rem; border-radius: 6px;
  background: var(--foreground); color: var(--background);
  font-size: 0.76rem; font-weight: 500; line-height: 1.55; letter-spacing: normal; text-align: left;
  opacity: 0; pointer-events: none; z-index: 20;
  box-shadow: 0 16px 32px -16px rgb(var(--foreground-rgb) / 0.45);
  transition: opacity var(--motion-micro) ease, transform var(--motion-micro) ease;
}
.trust-tip::after {
  content: ''; position: absolute; top: 100%; left: 50%; transform: translateX(-50%);
  border: 6px solid transparent; border-top-color: var(--foreground);
}
.trust-tip-trigger:hover .trust-tip,
.trust-tip-trigger:focus-visible .trust-tip,
.trust-tip-trigger[aria-expanded="true"] .trust-tip {
  opacity: 1; pointer-events: auto; transform: translate(-50%, 0);
}
@media (prefers-reduced-motion: reduce) {
  .trust-tip { transition: opacity 120ms ease; }
}

/* ===== Contextual reassurance row ==========================================
   Small reused strip for "no obligation / private / direct response"-style
   copy placed near forms and CTAs, per page context -- not a single isolated
   trust section but repeated in miniature wherever a visitor is deciding. */
.reassurance-row {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: 0.5rem 1.5rem; list-style: none;
  font-size: 0.78rem; color: var(--muted);
}
.reassurance-row li { display: inline-flex; align-items: center; gap: 0.4rem; }
.reassurance-row li svg { width: 14px; height: 14px; color: var(--accent); flex-shrink: 0; }

/* ===== "Where Websites Fall Short" problem cards / "What's Included"
   cards ============================================================
   Desktop: elevate + border brighten + a soft radial spotlight behind the
   card + a small icon nudge on hover. Deliberately no 3D tilt/rotation here
   (that's reserved for the Featured Work mockups where there's a real
   surface to tilt) -- these are plain info cards. Problem cards show all
   their content without hovering; included-cards additionally reveal an
   .included-detail panel on hover (desktop) or .is-expanded (tap, mirroring
   the Featured Work card's .card-tags reveal pattern) since their extra
   detail is genuinely optional reading, not core content. */
.problem-card, .included-card {
  position: relative;
  padding: 1.75rem 1.5rem;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--surface);
  transition: transform var(--motion-control) var(--motion-ease),
              border-color var(--motion-control) var(--motion-ease),
              box-shadow var(--motion-control) var(--motion-ease);
}
.problem-card::before, .included-card::before {
  content: '';
  position: absolute; inset: -1px; z-index: 0; border-radius: inherit; pointer-events: none;
  background: radial-gradient(220px circle at 50% 0%, rgb(var(--accent-rgb) / 0.14), transparent 70%);
  opacity: 0;
  transition: opacity var(--motion-control) ease;
}
.problem-card:hover, .included-card:hover, .included-card.is-expanded {
  transform: translateY(-3px);
  border-color: rgb(var(--accent-rgb) / 0.4);
  box-shadow: 0 20px 40px -28px rgb(var(--foreground-rgb) / 0.3);
}
.problem-card:hover::before, .included-card:hover::before, .included-card.is-expanded::before { opacity: 1; }
.problem-card-icon, .included-card-icon {
  position: relative; z-index: 1;
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; border-radius: 9999px;
  background: var(--background); color: var(--accent);
  transition: transform var(--motion-control) var(--motion-ease);
}
.problem-card:hover .problem-card-icon,
.included-card:hover .included-card-icon,
.included-card.is-expanded .included-card-icon {
  transform: scale(1.08) rotate(-4deg);
}
.problem-card h3, .problem-card p, .included-card h3, .included-card p { position: relative; z-index: 1; }

.included-toggle {
  position: absolute; top: 1.5rem; right: 1.5rem; z-index: 1;
  width: 26px; height: 26px; border-radius: 9999px; border: 1px solid var(--border-strong); color: var(--muted);
  display: inline-flex; align-items: center; justify-content: center;
  transition: transform var(--motion-control) var(--motion-ease), border-color var(--motion-control) ease, color var(--motion-control) ease;
}
.included-card:hover .included-toggle, .included-card.is-expanded .included-toggle {
  border-color: var(--accent); color: var(--accent);
}
.included-card.is-expanded .included-toggle { transform: rotate(45deg); }
.included-detail {
  position: relative; z-index: 1;
  max-height: 0; opacity: 0; overflow: hidden;
  transition: max-height 420ms cubic-bezier(0.22,1,0.36,1), opacity 300ms ease, margin-top 420ms cubic-bezier(0.22,1,0.36,1);
}
.included-card:hover .included-detail, .included-card.is-expanded .included-detail {
  max-height: 160px; opacity: 1; margin-top: 0.85rem;
}

@media (prefers-reduced-motion: reduce) {
  .problem-card, .problem-card-icon, .included-card, .included-card-icon, .included-toggle { transition: none !important; }
  .problem-card:hover, .included-card:hover, .included-card.is-expanded { transform: none; }
  .problem-card:hover .problem-card-icon,
  .included-card:hover .included-card-icon,
  .included-card.is-expanded .included-card-icon { transform: none; }
}

/* ===== Option pills (radio/checkbox selector cards) =======================
   Shared across Resource Center tools (Cost Estimator now; Launch Checklist
   and SEO Checklist later reuse the same component). Real native <input
   type="radio"/"checkbox"> visually hidden behind a styled <label> sibling,
   not a div with a click handler -- keyboard, screen reader, and browser
   autofill/validation all keep working exactly as they would for a plain
   checkbox. */
.option-pill-input {
  position: absolute; opacity: 0; width: 1px; height: 1px; overflow: hidden;
}
.option-pill {
  display: flex; align-items: center; justify-content: space-between; gap: 0.75rem;
  min-height: 52px; padding: 0.85rem 1.1rem; border-radius: 6px;
  border: 1px solid var(--border-strong); background: var(--surface); color: var(--foreground);
  font-size: 0.92rem; cursor: pointer; user-select: none;
  transition: border-color var(--motion-micro) ease, background-color var(--motion-micro) ease;
}
.option-pill-check {
  width: 20px; height: 20px; border-radius: 999px; flex-shrink: 0;
  border: 1.5px solid var(--border-strong); background: transparent;
  display: inline-flex; align-items: center; justify-content: center;
  transition: border-color var(--motion-micro) ease, background-color var(--motion-micro) ease;
}
.option-pill-input[type="checkbox"] + .option-pill .option-pill-check { border-radius: 4px; }
.option-pill-check svg { width: 12px; height: 12px; opacity: 0; color: var(--background); transition: opacity 120ms ease; }
.option-pill-input:checked + .option-pill { border-color: var(--accent); background: rgb(var(--accent-rgb) / 0.08); }
.option-pill-input:checked + .option-pill .option-pill-check { background: var(--accent); border-color: var(--accent); }
.option-pill-input:checked + .option-pill .option-pill-check svg { opacity: 1; }
.option-pill-input:focus-visible + .option-pill { outline: 2px solid var(--accent); outline-offset: 2px; }
.option-pill:hover { border-color: rgb(var(--accent-rgb) / 0.5); }
@media (prefers-reduced-motion: reduce) {
  .option-pill, .option-pill-check, .option-pill-check svg { transition: none !important; }
}

/* ===== Site search input =====================================
   Shared by the Resource Center's search and the homepage FAQ search --
   same visual treatment (pill input, leading icon) wherever a page needs
   client-side text filtering. */
.site-search {
  width: 100%; min-height: 52px; padding: 0.9rem 1.15rem 0.9rem 2.85rem; border-radius: 999px;
  border: 1px solid var(--border-strong); background: var(--surface); color: var(--foreground); font: inherit; font-size: 0.95rem;
  transition: border-color 200ms ease, box-shadow 200ms ease;
}
.site-search:focus-visible { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px rgb(var(--accent-rgb) / 0.22); }
.site-search-wrap { position: relative; }
.site-search-icon { position: absolute; left: 1.1rem; top: 50%; transform: translateY(-50%); width: 18px; height: 18px; color: var(--muted); pointer-events: none; }
