/* ==========================================================================
   NordCore polish layer — v1 (2026-07-25)
   --------------------------------------------------------------------------
   Shared across nordcore.site and its sub-sites. Purely additive: it refines
   motion, type rendering and interaction feedback on top of each page's own
   design. It deliberately does NOT change layout, colour identity or spacing,
   so it can be removed by deleting one <link> with no other consequence.

   Load it LAST in <head> so its equal-specificity rules win over the inline
   <style> blocks the pages already carry.
   ========================================================================== */

:root {
  /* One motion vocabulary instead of seven ad-hoc durations.
     `--ease-out` is a long-tail deceleration curve: things arrive quickly and
     settle gently, which is what reads as "smooth" rather than "animated". */
  --ease-out:      cubic-bezier(0.32, 0.72, 0, 1);
  --ease-in-out:   cubic-bezier(0.65, 0, 0.35, 1);
  --ease-spring:   cubic-bezier(0.34, 1.4, 0.64, 1);

  --dur-fast:   140ms;   /* colour/opacity on small controls   */
  --dur-base:   260ms;   /* the default for hover states       */
  --dur-slow:   420ms;   /* cards, panels, anything with size  */
  --dur-enter:  680ms;   /* first paint / scroll reveal        */

  /* Brand accent for focus rings and selection. Each sub-site can override
     --polish-accent-rgb in its own CSS so the ring matches its palette
     (grabbit is carrot/lime, drift is teal) instead of the platform purple. */
  --polish-accent-rgb: 196, 181, 253;
  --ring:
    0 0 0 2px rgba(var(--polish-accent-rgb), 0.85),
    0 0 0 6px rgba(var(--polish-accent-rgb), 0.22);
}

/* --------------------------------------------------------------------------
   1. Type rendering. The pages set no smoothing at all, which on Apple
   displays leaves the glass UI looking slightly heavy and fuzzy. This is the
   single cheapest crispness win available.
   -------------------------------------------------------------------------- */
html {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  -webkit-text-size-adjust: 100%;
}

/* Display type reads tighter and more deliberate at large sizes. */
:where(h1, h2, .card-title) {
  letter-spacing: -0.018em;
  text-wrap: balance;
}
:where(p, .card-sub, .sec-lead, .faq-a) {
  text-wrap: pretty;
}

/* Numbers in tiles/stats stop jittering as they change. */
:where(.svc-badge, .badge, time, [data-numeric]) {
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   2. Scrolling. Anchor jumps previously landed underneath the sticky nav.
   -------------------------------------------------------------------------- */
html:focus-within { scroll-behavior: smooth; }
:where(section, [id]) { scroll-margin-top: 84px; }

/* --------------------------------------------------------------------------
   3. Interaction feedback. Same curve everywhere, plus a real press state —
   a small, fast scale-down is what makes a UI feel physical rather than flat.
   -------------------------------------------------------------------------- */
.svc-tile {
  transition:
    background     var(--dur-base) var(--ease-out),
    border-color   var(--dur-base) var(--ease-out),
    transform      var(--dur-slow) var(--ease-out),
    box-shadow     var(--dur-slow) var(--ease-out);
  will-change: transform;
}
.svc-tile:hover {
  transform: translateY(-5px);
  /* Layered shadow reads as depth; a single hard shadow reads as a sticker. */
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.10),
    0 2px 6px rgba(0, 0, 0, 0.18),
    0 14px 34px -12px rgba(0, 0, 0, 0.48);
}
.svc-tile:active { transform: translateY(-2px) scale(0.995); transition-duration: var(--dur-fast); }

:where(.service-btn, .btn-solid, .b-open, .b-member, .switcher__option) {
  transition:
    background   var(--dur-fast) var(--ease-out),
    border-color var(--dur-fast) var(--ease-out),
    color        var(--dur-fast) var(--ease-out),
    transform    var(--dur-base) var(--ease-out),
    box-shadow   var(--dur-base) var(--ease-out);
}
:where(.service-btn, .btn-solid, .b-open, .b-member):active {
  transform: scale(0.975);
  transition-duration: 90ms;
}

/* The arrow leading the eye on service rows. */
.srv-arrow { transition: transform var(--dur-base) var(--ease-out); }
:where(.svc-tile, .service-btn):hover .srv-arrow { transform: translateX(3px); }

/* --------------------------------------------------------------------------
   4. Scroll reveal. The page already observes `.reveal` and adds `.in`;
   this only refines the curve and staggers siblings so a row of tiles
   arrives as a sequence rather than a single block.
   -------------------------------------------------------------------------- */
.js-reveal .reveal {
  transition:
    opacity   var(--dur-enter) var(--ease-out),
    transform var(--dur-enter) var(--ease-out);
}
.js-reveal .reveal:nth-child(2)  { transition-delay: 60ms;  }
.js-reveal .reveal:nth-child(3)  { transition-delay: 120ms; }
.js-reveal .reveal:nth-child(4)  { transition-delay: 180ms; }
.js-reveal .reveal:nth-child(5)  { transition-delay: 240ms; }
.js-reveal .reveal:nth-child(n+6){ transition-delay: 300ms; }

/* --------------------------------------------------------------------------
   5. Focus. One visible, branded ring on every interactive element — keyboard
   users currently get whatever each control happened to define.
   -------------------------------------------------------------------------- */
/* No border-radius here on purpose: box-shadow already follows the element's
   own radius, and forcing one reshapes circular controls (e.g. the round send
   button in the support chat). */
:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: none;
  box-shadow: var(--ring);
  transition: box-shadow var(--dur-fast) var(--ease-out);
}

/* --------------------------------------------------------------------------
   6. Glass fallback. backdrop-filter is used 34x; without it the translucent
   surfaces become near-unreadable rather than merely flat.
   -------------------------------------------------------------------------- */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  :where(.svc-tile, .main-card, .card-face, .nav, nav) {
    /* Falls back to each site's own --bg, not a hardcoded platform colour. */
    background-color: var(--polish-solid, var(--bg, rgba(26, 4, 16, 0.92)));
  }
}

/* --------------------------------------------------------------------------
   7. Small surface details.
   -------------------------------------------------------------------------- */
/* No forced text colour: these pages ship dark, light and dim themes, and
   hardcoding #fff made selected text invisible on the light ones. */
::selection { background: rgba(var(--polish-accent-rgb), 0.30); }

/* Kill the grey flash on tap without disabling focus feedback. */
:where(a, button, .svc-tile, .service-btn) { -webkit-tap-highlight-color: transparent; }

/* A scrollbar that belongs to the design rather than the OS.
   Uses a mid grey with alpha so it stays visible on dark, dim AND light
   themes -- a white thumb vanished entirely on the light ones. Sites that
   want a different weight can set --polish-scroll-rgb. */
:root { --polish-scroll-rgb: 141, 141, 150; }

@supports (scrollbar-color: auto) {
  html {
    scrollbar-color: rgba(var(--polish-scroll-rgb), 0.45) transparent;
    scrollbar-width: thin;
  }
}
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: rgba(var(--polish-scroll-rgb), 0.42);
  border-radius: 999px;
  border: 2px solid transparent;
  background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover {
  background: rgba(var(--polish-scroll-rgb), 0.65);
  background-clip: content-box;
}

/* Images shouldn't reflow the page while they load. */
:where(img) { max-width: 100%; height: auto; }

/* --------------------------------------------------------------------------
   8. Reduced motion wins over everything above.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html:focus-within { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }
  .svc-tile:hover, .svc-tile:active,
  :where(.service-btn, .btn-solid, .b-open, .b-member):active { transform: none; }
}
