/* ==========================================================================
   AKSO — Global Utilities
   Loaded last, after the design-system files (variables → reset →
   typography → grid → sections → nav → footer) and before any
   page-specific stylesheet. Contains cross-page utility classes only —
   composition/one-off layout belongs in assets/css/pages/*.css.

   NOTE ON LOAD STRATEGY: stylesheets are linked individually in each
   page <head> rather than combined via @import, since @import creates a
   sequential request waterfall that delays first paint. Keeping them as
   separate <link> tags lets the browser fetch the whole design system in
   parallel. For a production deploy, run them through a simple
   concatenate + minify step (e.g. esbuild/postcss-cli) as a build command
   in Cloudflare Pages — no runtime framework required.
   ========================================================================== */

/* ---------------------------------------------------------------------
   Layout utilities
   --------------------------------------------------------------------- */
.u-hidden { display: none !important; }

@media (max-width: 768px) {
  .u-hide-mobile { display: none !important; }
}

@media (min-width: 769px) {
  .u-hide-desktop { display: none !important; }
}

.u-relative { position: relative; }
.u-full-width { width: 100%; }

/* ---------------------------------------------------------------------
   Spacing utilities — used sparingly, for one-off adjustments only.
   Prefer composing with .section / .grid gap tokens first.
   --------------------------------------------------------------------- */
.u-mt-1 { margin-top: var(--space-1); }
.u-mt-2 { margin-top: var(--space-2); }
.u-mt-3 { margin-top: var(--space-3); }
.u-mt-4 { margin-top: var(--space-4); }
.u-mt-5 { margin-top: var(--space-5); }
.u-mt-6 { margin-top: var(--space-6); }

.u-mb-1 { margin-bottom: var(--space-1); }
.u-mb-2 { margin-bottom: var(--space-2); }
.u-mb-3 { margin-bottom: var(--space-3); }
.u-mb-4 { margin-bottom: var(--space-4); }
.u-mb-5 { margin-bottom: var(--space-5); }
.u-mb-6 { margin-bottom: var(--space-6); }

/* ---------------------------------------------------------------------
   Text utilities
   --------------------------------------------------------------------- */
.u-text-center { text-align: center; }
.u-text-right  { text-align: right; }
.u-balance     { text-wrap: balance; }

/* ---------------------------------------------------------------------
   Aspect ratio helpers — for image/video frames with reserved space,
   preventing layout shift before lazy media loads.
   --------------------------------------------------------------------- */
.aspect-portrait  { aspect-ratio: 4 / 5; }
.aspect-landscape { aspect-ratio: 3 / 2; }
.aspect-square    { aspect-ratio: 1 / 1; }
.aspect-wide      { aspect-ratio: 16 / 9; }
.aspect-cinema    { aspect-ratio: 21 / 9; }

/* ---------------------------------------------------------------------
   Page transition overlay — shared shell, driven by
   assets/js/core/page-transitions.js

   Opaque by default: this is the safe pre-JS state. The very first
   paint of every page is fully covered by this layer, so there is
   never a flash of unstyled/half-loaded content — the script fades it
   out once the page (including injected nav/footer partials) is
   actually ready. If JavaScript never runs at all, the matching
   <noscript> rule in every page's <head> forces display:none instead,
   so content is never permanently hidden for no-JS visitors.

   All animated state after that is owned directly by GSAP (inline
   styles), not CSS classes/transitions — keeps a single source of
   truth for timing and easing, right next to the click-intercept logic
   that decides when to trigger it.
   --------------------------------------------------------------------- */
.page-transition {
  position: fixed;
  inset: 0;
  z-index: var(--z-transition);
  background-color: var(--color-bg);
  opacity: 1;
  pointer-events: none;
}

/* ---------------------------------------------------------------------
   Custom cursor — desktop only, disabled on touch devices by JS
   (cursor.js adds .has-custom-cursor to <body> after feature-detection)
   --------------------------------------------------------------------- */
.cursor-dot,
.cursor-ring {
  position: fixed;
  top: 0;
  left: 0;
  z-index: var(--z-cursor);
  pointer-events: none;
  border-radius: 50%;
  transform: translate(-50%, -50%);
  opacity: 0;
  transition: opacity var(--duration-fast) var(--ease-standard);
}

.has-custom-cursor .cursor-dot,
.has-custom-cursor .cursor-ring {
  opacity: 1;
}

.cursor-dot {
  width: 6px;
  height: 6px;
  background-color: var(--color-text-primary);
}

.cursor-ring {
  width: 36px;
  height: 36px;
  border: 1px solid var(--color-text-primary);
  transition: opacity var(--duration-fast) var(--ease-standard),
              width var(--duration-fast) var(--ease-standard),
              height var(--duration-fast) var(--ease-standard);
}

.cursor-ring.is-active {
  width: 64px;
  height: 64px;
}

@media (max-width: 1024px) {
  .cursor-dot,
  .cursor-ring {
    display: none;
  }
}
