/* ==========================================================================
   CSR FINAL POLISH LAYER
   Additive finishing pass shared across the site. Everything here is
   namespaced (.polish-*), gated behind capability checks, and safe to load
   on any page: it never restructures layout and never overrides page logic.

   Motion tokens (single source of truth):
     ease  : cubic-bezier(0.16, 1, 0.3, 1)  - matches the site's existing ease
     fast  : 180ms  - micro-interactions (hover, press, underline)
     slow  : 700ms  - reveals and settles

   Page flags, set by polish.js on <html data-polish="...">:
     "home"  - the landing page (index.html)
     "cards" - a page with the .catalog-grid instrument cards
     "seo"   - a page that links seo-pages.css (research/notes/el-paso/border)
   ========================================================================== */

:root {
  --polish-ease: cubic-bezier(0.16, 1, 0.3, 1);
  --polish-fast: 180ms;
  --polish-slow: 700ms;
  --polish-spot-a: rgba(255, 107, 53, 0.085);
  --polish-spot-b: rgba(125, 201, 162, 0.05);
  --polish-corner-a: rgba(255, 190, 11, 0.55);
  --polish-corner-b: rgba(125, 201, 162, 0.55);
}

html[data-theme="light"] {
  --polish-spot-a: rgba(255, 107, 53, 0.07);
  --polish-spot-b: rgba(125, 201, 162, 0.045);
  --polish-corner-a: rgba(176, 122, 6, 0.5);
  --polish-corner-b: rgba(38, 122, 84, 0.5);
}

/* ==========================================================================
   1. FILM GRAIN - fixed, full-bleed, non-interactive atmosphere layer.
   Injected by polish.js. Sits above content like emulsion on a print.
   Animates with discrete steps() jumps on transform only; static under
   reduced motion and on small screens.
   ========================================================================== */

.polish-grain {
  position: fixed;
  inset: -14px;
  z-index: 9990;
  pointer-events: none;
  opacity: 0.05;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%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");
  background-size: 160px 160px;
}

html[data-theme="light"] .polish-grain { opacity: 0.06; }

@media (prefers-reduced-motion: no-preference) and (min-width: 801px) {
  .polish-grain {
    animation: polishGrain 1.1s steps(1, end) infinite;
  }
}

@keyframes polishGrain {
  0%, 100% { transform: translate3d(0, 0, 0); }
  10% { transform: translate3d(-9px, 5px, 0); }
  20% { transform: translate3d(7px, -8px, 0); }
  30% { transform: translate3d(-5px, 9px, 0); }
  40% { transform: translate3d(9px, 4px, 0); }
  50% { transform: translate3d(-8px, -6px, 0); }
  60% { transform: translate3d(4px, 8px, 0); }
  70% { transform: translate3d(8px, -4px, 0); }
  80% { transform: translate3d(-4px, -9px, 0); }
  90% { transform: translate3d(6px, 6px, 0); }
}

/* ==========================================================================
   2. SCROLL TELEMETRY - 2px progress filament across the very top.
   Ember to brass to phosphor, mirroring the assembly progress strip.
   Scroll-linked (mirrors user input), so it stays active under reduced
   motion. CSS scroll-timeline where supported; polish.js drives a
   transform fallback elsewhere.
   ========================================================================== */

.polish-progress {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  z-index: 9991;
  pointer-events: none;
  background: linear-gradient(90deg, #FF6B35, #FFBE0B 52%, #7DC9A2);
  transform: scaleX(0);
  transform-origin: 0 50%;
}

@supports (animation-timeline: scroll(root)) {
  .polish-progress {
    animation: polishProgress linear both;
    animation-timeline: scroll(root);
  }
}

@keyframes polishProgress {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

/* ==========================================================================
   3. PAGE TRANSITIONS - same-origin MPA cross-fade via the View
   Transitions API. Progressive enhancement: browsers without support
   navigate exactly as before.
   ========================================================================== */

@media (prefers-reduced-motion: no-preference) {
  @view-transition {
    navigation: auto;
  }
}

/* ==========================================================================
   4. NAV MICRO-INTERACTION - underline grows from the left on hover and
   keyboard focus, landing exactly where the active-page underline sits.
   ========================================================================== */

@media (hover: hover) {
  nav ul a:not(.active)::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: -6px;
    height: 1px;
    background: var(--red, #FF6B35);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform var(--polish-fast) var(--polish-ease);
  }
  nav ul a:not(.active):hover::after,
  nav ul a:not(.active):focus-visible::after {
    transform: scaleX(1);
  }
}

/* ==========================================================================
   5. FOCUS VISIBILITY - a consistent brand focus ring, added (never
   removed) for keyboard navigation. :where() keeps specificity at zero
   so page-level focus styling always wins if it exists.
   ========================================================================== */

:where(a, button, .btn, .button, .theme-toggle):focus-visible {
  outline: 2px solid var(--red, #FF6B35);
  outline-offset: 3px;
}

/* ==========================================================================
   6. BUTTON FEEDBACK - landing page .btn and seo-page .button get a
   quiet lift and a press state. Uses the standalone translate property,
   leaving each page's own transform mechanics untouched.
   ========================================================================== */

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  html[data-polish~="home"] .btn,
  html[data-polish~="seo"] .button {
    transition: color 0.2s, background-color 0.25s, border-color 0.25s,
                translate var(--polish-fast) var(--polish-ease);
    will-change: auto;
  }
  html[data-polish~="home"] .btn:hover,
  html[data-polish~="seo"] .button:hover {
    translate: 0 -2px;
  }
  html[data-polish~="home"] .btn:active,
  html[data-polish~="seo"] .button:active {
    translate: 0 0;
    transition-duration: 0.2s, 0.25s, 0.25s, 80ms;
  }
}

/* ==========================================================================
   7. CARD PRESENCE - instrument cards (landing catalog) and seo cards
   gain a gentle lift, a cursor-tracking spotlight, and the assembly
   frame's corner brackets (brass top-left, phosphor bottom-right).
   The spotlight and brackets live on one ::after layer: opacity is the
   only animated property.
   ========================================================================== */

html[data-polish~="cards"] .instrument,
html[data-polish~="cards"] .instrument-card {
  /* restates the card's own background/border transition, then extends it */
  position: relative;
  transition: background 0.3s, border-color 0.3s,
              box-shadow 0.45s var(--polish-ease),
              translate 0.45s var(--polish-ease);
}

html[data-polish~="seo"] .card {
  position: relative;
  transition: border-color 0.3s,
              box-shadow 0.45s var(--polish-ease),
              translate 0.45s var(--polish-ease);
}

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  html[data-polish~="cards"] .instrument:hover,
  html[data-polish~="cards"] .instrument-card:hover {
    translate: 0 -4px;
  }
  html[data-polish~="seo"] .card:hover {
    translate: 0 -3px;
    box-shadow: 0 18px 44px rgba(0, 0, 0, 0.38);
  }

  html[data-polish~="cards"] .instrument::after,
  html[data-polish~="cards"] .instrument-card::after,
  html[data-polish~="seo"] .card::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    border-radius: inherit;
    opacity: 0;
    transition: opacity 0.45s var(--polish-ease);
    background-image:
      linear-gradient(var(--polish-corner-a), var(--polish-corner-a)),
      linear-gradient(var(--polish-corner-a), var(--polish-corner-a)),
      linear-gradient(var(--polish-corner-b), var(--polish-corner-b)),
      linear-gradient(var(--polish-corner-b), var(--polish-corner-b)),
      radial-gradient(380px circle at var(--mx, 50%) var(--my, 38%),
        var(--polish-spot-a), var(--polish-spot-b) 42%, transparent 70%);
    background-repeat: no-repeat;
    background-size: 16px 1px, 1px 16px, 16px 1px, 1px 16px, 100% 100%;
    background-position: left 8px top 8px, left 8px top 8px,
                         right 8px bottom 8px, right 8px bottom 8px,
                         0 0;
  }
  html[data-polish~="cards"] .instrument:hover::after,
  html[data-polish~="cards"] .instrument-card:hover::after,
  html[data-polish~="seo"] .card:hover::after {
    opacity: 1;
  }
}

/* ==========================================================================
   8. SCROLL REVEALS - polish.js tags below-the-fold seo cards with
   .polish-reveal and flips them to .polish-in as they enter the viewport.
   Under reduced motion nothing is tagged, and this fallback guarantees
   visibility even if the class lands anyway.
   ========================================================================== */

.polish-reveal {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity var(--polish-slow) var(--polish-ease),
              transform var(--polish-slow) var(--polish-ease);
  transition-delay: var(--polish-delay, 0ms);
}

.polish-reveal.polish-in {
  opacity: 1;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .polish-reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* ==========================================================================
   9. LAB FILMS - silent brand films in an instrument bezel. The frame owns
   its aspect ratio (zero CLS); playback is IntersectionObserver-driven from
   polish.js and never starts under reduced motion or Save-Data, leaving the
   poster as a still. Corner ticks reuse the assembly bracket accents.
   ========================================================================== */

.polish-film {
  margin: var(--space-48) 0 0;
}

.polish-film-frame {
  position: relative;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  border: 1px solid var(--hair);
  border-radius: var(--radius-lg);
  background: #000;
  box-shadow: var(--shadow-soft);
}

.polish-film-frame video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.polish-film-frame::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  border-radius: inherit;
  background-image:
    linear-gradient(var(--polish-corner-a), var(--polish-corner-a)),
    linear-gradient(var(--polish-corner-a), var(--polish-corner-a)),
    linear-gradient(var(--polish-corner-b), var(--polish-corner-b)),
    linear-gradient(var(--polish-corner-b), var(--polish-corner-b));
  background-repeat: no-repeat;
  background-size: 16px 1px, 1px 16px, 16px 1px, 1px 16px;
  background-position: left 10px top 10px, left 10px top 10px,
                       right 10px bottom 10px, right 10px bottom 10px;
}

.polish-film-caption {
  margin-top: var(--space-12);
  font-family: var(--font-mono);
  font-size: var(--text-caption);
  color: var(--muted);
  letter-spacing: 0.04em;
}

/* ==========================================================================
   10. TEXT + SCROLL DETAILS
   ========================================================================== */

::selection {
  background: var(--orange);
  color: #000;
}

html[data-theme="light"] ::selection {
  color: #FFF;
}

html {
  overscroll-behavior-y: none;
  scrollbar-width: thin;
  scrollbar-color: var(--hair-active) transparent;
}

[id] {
  scroll-margin-top: 96px;
}

h1, h2, h3 {
  text-wrap: balance;
}

p {
  text-wrap: pretty;
}

.mono, code, .catalog-meta, .footer-registry {
  font-variant-numeric: tabular-nums;
}

/* Deep-link acknowledgement: the target section's marker ring fades out. */
@media (prefers-reduced-motion: no-preference) {
  section:target, [id]:target {
    animation: polishTarget 1.4s var(--polish-ease) 1;
  }
}

@keyframes polishTarget {
  0% { outline: 2px solid var(--orange); outline-offset: 8px; }
  100% { outline: 2px solid transparent; outline-offset: 14px; }
}

/* ==========================================================================
   HOUSEKEEPING
   ========================================================================== */

@media print {
  .polish-grain,
  .polish-progress,
  .polish-film,
  nav, .site-nav, .nav-island,
  video, audio,
  .theme-toggle {
    display: none !important;
  }

  html, body {
    background: #FFF !important;
    color: #000 !important;
  }

  main a[href^="http"]::after,
  main a[href^="/"]::after {
    content: " (" attr(href) ")";
    font-size: 0.85em;
    color: #555;
  }
}
