/* ============================================================================
   site.css — Front-end design system + page styles (Phase 1)

   Structure of this file:
     1. Design tokens (:root variables)  ← change theme/layout/animation HERE
     2. Base / reset
     3. Icon utility (ONE recolorable SVG set, tinted via currentColor)
     4. Menu bar (centered nav island; dark variant on HOME)
     5. Content container + the shared "dock-in" animation
     6. HOME page (background cycler, video, social icons)
     7. LINKS page (categorized external links)
     8. Simple page stubs (gallery / commissions placeholders)
     9. Responsive rules (stacking on narrow screens)

   Theming note: every color, size, and timing you might want to tweak lives as a
   custom property in section 1. The later "CSS refinement pass" should only need to
   touch :root. Values below are NEUTRAL PLACEHOLDERS.
   ============================================================================ */

/* ---------------------------------------------------------------------------
   1. DESIGN TOKENS — single source of truth for theme, layout, and motion.
   --------------------------------------------------------------------------- */
:root {
  /* Layout widths (from the spec — menu and content share one width: 1280px). */
  --menu-width: 1280px;         /* max width of the centered menu island           */
  --content-width: 1280px;      /* max width of page content                       */
  --gutter: 1.5rem;             /* horizontal breathing room on small screens      */
  --stack-breakpoint: 720px;    /* at/below this, menu + content go single-column   */
                                /* (media queries must repeat the literal 720px)    */

  /* Color palette (neutral placeholders — replaced in the theming pass). */
  --color-bg: #ffffff;          /* site background                                  */
  --color-text: #1a1a1a;        /* default text + default icon tint                 */
  --color-muted: #6b6b6b;       /* secondary text                                  */
  --color-accent: #2b2b2b;      /* links / active nav                              */
  --menu-blur: 20px;            /* backdrop blur strength behind the menu bar       */

  /* Default (light pages) menu bar look. */
  --menu-bg: rgba(255,255,255,0.55);
  --menu-border: rgba(0,0,0,0.08);
  --menu-fg: var(--color-text);

  /* HOME menu bar look (dark, because HOME backgrounds are mostly dark). */
  --menu-bg-home: rgba(0,0,0,0.50);     /* black @ 50%                              */
  --menu-border-home: rgba(255,255,255,0.15);
  --menu-fg-home: #ffffff;              /* text + icons go white                    */

  /* Typography. */
  --font-body: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-size: 16px;
  --nav-letterspacing: 0.08em;

  /* Motion — the shared "dock from below + fade in" animation. Reused for page
     loads AND gallery tiles, so editing these changes both consistently. */
  --anim-dock-duration: 520ms;  /* length of one dock-in                            */
  --anim-dock-distance: 28px;   /* how far below its resting place an item starts   */
  --anim-dock-stagger: 70ms;    /* delay added per sequential item (tiles/icons)    */
  --anim-ease: cubic-bezier(0.22, 0.61, 0.36, 1); /* soft ease-out                  */

  /* HOME background cycler crossfade duration (JS also reads real values from config). */
  --bg-fade-duration: 2000ms;

  /* Z-index layers. */
  --z-background: 0;
  --z-content: 10;
  --z-menu: 100;
}

/* ---------------------------------------------------------------------------
   2. BASE / RESET — minimal, intentionally simple (refined later).
   --------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html, body { margin: 0; padding: 0; }

body {
  font-family: var(--font-body);
  font-size: var(--font-size);
  color: var(--color-text);
  background: var(--color-bg);
  line-height: 1.5;
  /* Sticky-footer scaffold: the page is a vertical flex column at least as tall
     as the viewport, so the footer (last in-flow child) is pushed to the bottom
     even when the content is short. The fixed menu + background cycler are
     position:fixed and sit outside this flow, so they're unaffected.

     Height uses dvh (dynamic viewport height) with a vh fallback: on mobile Safari
     `100vh` is the LARGE viewport (as if the browser toolbars were hidden), which is
     taller than the visible area — that extra height is exactly what let the page
     scroll just enough to reveal the footer. `100dvh` tracks the currently visible
     height, so the page fits with no phantom scrollbar. */
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

a { color: var(--color-accent); }

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

/* ---------------------------------------------------------------------------
   3. ICON UTILITY — one recolorable SVG set.

   How it works: the SVG is used as a CSS *mask*, and the element is filled with
   `currentColor`. So a single monochrome outline SVG is tinted by whatever text
   color applies — white on the dark HOME menu, dark on light pages — with NO second
   icon set. Each icon element sets its own file via the inline `--icon` variable:
       <span class="icon" style="--icon:url('/assets/icons/foo.svg')"></span>
   Requirement: the source SVG must be opaque shapes/strokes on a transparent
   background (our outline icons already are) — the mask uses its alpha channel.
   --------------------------------------------------------------------------- */
.icon {
  display: inline-block;
  vertical-align: middle;
  background-color: currentColor;                 /* the tint */
  -webkit-mask: var(--icon) center / contain no-repeat;
          mask: var(--icon) center / contain no-repeat;
}

/* ---------------------------------------------------------------------------
   4. MENU BAR — centered nav island; logo + admin key are pinned to the edges so
   the nav is centered relative to the WHOLE bar (not between logo and key).
   --------------------------------------------------------------------------- */
.menu {
  position: fixed;
  top: 0; left: 0; right: 0;         /* docked flush to the top window edge */
  z-index: var(--z-menu);
  /* The bar spans the full window width with square corners; its content is
     constrained to --menu-width and centered by .menu__island. */
  color: var(--menu-fg);
  background: var(--menu-bg);
  border-bottom: 1px solid var(--menu-border);
  /* The blur that frosts whatever is behind the bar (e.g. the HOME background). */
  backdrop-filter: blur(var(--menu-blur));
  -webkit-backdrop-filter: blur(var(--menu-blur));
}

.menu__island {
  position: relative;        /* anchor for the absolutely-placed logo + key */
  width: 100%;
  max-width: var(--menu-width);
  min-height: 48px;
  margin: 0 auto;            /* center the content within the full-width bar */
  padding: 0.5rem var(--gutter);
  display: flex;
  align-items: center;
  justify-content: center;   /* centers the nav within the bar */
}

/* Logo pinned left, vertically centered. Tinted by the island's currentColor. */
.menu__logo {
  position: absolute;
  left: var(--gutter); top: 50%;
  transform: translateY(-50%);
  display: inline-flex;
  color: inherit;            /* so the masked logo follows the menu text color */
}
.menu__logo-icon { width: 120px; height: 28px; }

/* Centered primary navigation. */
.menu__nav {
  display: flex;
  justify-content: center;
  gap: 1.25rem;
}
.menu__link {
  text-decoration: none;
  color: var(--menu-fg);
  letter-spacing: var(--nav-letterspacing);
  font-size: 0.85rem;
  padding: 0.25rem 0;
  border-bottom: 2px solid transparent;
  transition: border-color 180ms var(--anim-ease), opacity 180ms var(--anim-ease);
}
.menu__link:hover { opacity: 0.7; }
.menu__link.is-active { border-bottom-color: currentColor; }

/* Admin key pinned right, vertically centered. */
.menu__admin {
  position: absolute;
  right: var(--gutter); top: 50%;
  transform: translateY(-50%);
  display: inline-flex;
  color: inherit;
  opacity: 0.75;
  transition: opacity 180ms var(--anim-ease), transform 180ms var(--anim-ease);
}
.menu__admin:hover { opacity: 1; transform: translateY(-50%) scale(1.1); }
.menu__admin-icon { width: 20px; height: 20px; }

/* HOME dark menu variant (applied because <body> carries .page-home). */
body.page-home .menu {
  color: var(--menu-fg-home);
  background: var(--menu-bg-home);
  border-color: var(--menu-border-home);
}
body.page-home .menu__link { color: var(--menu-fg-home); }

/* ---------------------------------------------------------------------------
   5. CONTENT CONTAINER + shared DOCK-IN animation.

   Any element marked `data-dock` starts translated down + transparent, then site.js
   adds `.is-docked` to animate it to rest. Sequential items (tiles/icons) get a
   per-item delay via the inline `--i` index variable so they cascade. Centralizing
   this here means gallery tiles (Phase 2) reuse the exact same motion.
   --------------------------------------------------------------------------- */
.content {
  position: relative;
  z-index: var(--z-content);
  width: 100%;
  max-width: var(--content-width);
  margin: 0 auto;
  padding: 7rem var(--gutter) 4rem; /* top padding clears the fixed menu bar */
  flex: 1 0 auto;                   /* grow to fill height so the footer docks to the bottom */
}

[data-dock] {
  opacity: 0;
  transform: translateY(var(--anim-dock-distance));
  transition:
    opacity var(--anim-dock-duration) var(--anim-ease),
    transform var(--anim-dock-duration) var(--anim-ease);
  transition-delay: calc(var(--i, 0) * var(--anim-dock-stagger));
}
[data-dock].is-docked { opacity: 1; transform: translateY(0); }

/* Respect users who prefer reduced motion: show content immediately, no sliding. */
@media (prefers-reduced-motion: reduce) {
  [data-dock] { opacity: 1; transform: none; transition: none; }
}

/* ---------------------------------------------------------------------------
   6. HOME page.
   --------------------------------------------------------------------------- */

/* Full-frame background cycler. Two stacked layers crossfade (see site.js). */
.bg-cycler {
  position: fixed;
  inset: 0;
  z-index: var(--z-background);
  overflow: hidden;
  background: #000; /* shown behind images while the first one loads */
}
.bg-cycler__layer {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  opacity: 0;
  transition: opacity var(--bg-fade-duration) linear;
}
.bg-cycler__layer.is-visible { opacity: 1; }

/* HOME content sits above the background; center the column horizontally AND
   vertically so the headline / video button / social icons are at window centre
   height. Text is white here because the backgrounds are mostly dark; this also
   tints the social icons white.

   The body is a flex column filling the viewport.  .content flex-grows into the
   remaining space and centers .home inside it.  The footer stays at the bottom.
   A scrollbar appears ONLY when the three elements genuinely don't fit. */
body.page-home {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}
.page-home .content {
  flex: 1;                 /* fill the remaining vertical space between menu + footer */
  display: flex;
  flex-direction: column;
  justify-content: center;  /* vertical centering of .home */
  padding-top: 0;
  padding-bottom: 0;
}
.page-home .home { color: #ffffff; }
.home {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2rem;
  text-align: center;
}

/* Admin-managed headline above the video. Inherits the white .home text color; the
   shadow keeps it legible over bright patches of the background images.
   Font-size uses viewport units so it scales down dynamically on narrow screens
   (iPhone, etc.) and always stays on a single line.  !important overrides any
   inline font-size from the WYSIWYG editor. */
.home-headline {
  max-width: var(--menu-width);
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.85);
  white-space: nowrap;
  font-size: clamp(0.5rem, 2vw, 0.95rem);
}
.home-headline * {
  font-size: inherit !important;
  white-space: nowrap !important;
}
.home-headline :first-child { margin-top: 0; }
.home-headline :last-child { margin-bottom: 0; }
.home-headline h2 { font-size: 1.8rem; letter-spacing: var(--nav-letterspacing); }
.home-headline h3 { font-size: 1.3rem; }
.home-headline a { color: inherit; }

/* Dotted separator produced by the rich-text editors' "— ·· —" button. The server
   whitelists <hr> (lib/sanitize.php); it renders as a dotted rule that adapts to the
   surrounding text color (white on HOME, dark on light pages). */
.home-headline hr,
.site-footer hr,
.cmsn-tos hr,
.cmsn-disclaimer hr {
  border: 0;
  border-top: 2px dotted currentColor;
  opacity: 0.45;
  margin: 1.1rem 0;
}

/* The Vimeo reel. The padding-top box is the bulletproof responsive technique:
   height is derived from width (56.25% = 16:9), so it can never collapse to 0 the
   way `aspect-ratio` can inside a centered flex column. Width matches the menu. */
.video-container {
  position: relative;
  width: 100%;
  max-width: var(--menu-width);
  height: 0;
  padding-top: 56.25%;              /* 16:9 */
  border-radius: 12px;
  overflow: hidden;
  background: #000;
  box-shadow: 0 10px 40px rgba(0,0,0,0.35);
}
.video-container iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

/* --- Idle animations that entice the visitor to click the video button.
   Both stop the moment any expand class is added (see overrides below). --- */
@keyframes video-btn-pulse {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.03); }
}
@keyframes video-btn-shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* ---------------------------------------------------------------------------
   Video button box (HOME page) — replaces the always-loaded .video-container.
   Starts as a compact frosted-glass pill (same styling as the menu bar:
   black 50% + backdrop blur), then expands width + height together → reveals
   the iframe.  The iframe is injected into the DOM only after unfolding
   completes, so it never loads/autoplays early.

   The JS-driven expand sequence:
     1. .is-width-expanded + .is-height-expanded added together
        (pill grows diagonally to --menu-width × 16:9)
     2. iframe injected into .video-button-box__video + .is-video-visible
        (iframe fades in over the dark background)
   --------------------------------------------------------------------------- */
.video-button-box {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;

  /* Same frosted-glass treatment as the menu bar on HOME. */
  background: var(--menu-bg-home);
  backdrop-filter: blur(var(--menu-blur));
  -webkit-backdrop-filter: blur(var(--menu-blur));

  border-radius: 12px;
  overflow: hidden;
  cursor: pointer;
  user-select: none;

  /* Initial compact button state. */
  width: auto;
  max-width: var(--menu-width);
  height: auto;
  padding: 0.85rem 2.2rem;

  /* Idle pulse: subtle scale breathing after the dock-in finishes. */
  animation: video-btn-pulse 2.8s ease-in-out infinite;
  animation-delay: 0.75s;   /* let dock-in complete before pulsing */

  /* All dimension changes animate at the admin-configured unfold speed.
     The --unfold-speed variable is set by site.js from the config value.
     opacity + transform are included so the data-dock fade-in/rise still runs. */
  --unfold-speed: 600ms;
  transition: opacity var(--anim-dock-duration) var(--anim-ease),
              transform var(--anim-dock-duration) var(--anim-ease),
              width var(--unfold-speed) var(--anim-ease),
              max-width var(--unfold-speed) var(--anim-ease),
              height var(--unfold-speed) var(--anim-ease),
              padding var(--unfold-speed) var(--anim-ease),
              border-radius var(--unfold-speed) var(--anim-ease);
}

/* Shimmer sweep across the frosted-glass surface.  Sits behind the text so
   the label stays crisp.  Stops when any expand class is added. */
.video-button-box::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  background: linear-gradient(
    115deg,
    transparent       30%,
    rgba(255,255,255,0.10) 45%,
    rgba(255,255,255,0.20) 50%,
    rgba(255,255,255,0.10) 55%,
    transparent       70%
  );
  background-size: 200% 100%;
  animation: video-btn-shimmer 3.5s ease-in-out infinite;
  animation-delay: 1.2s;   /* slightly offset from the pulse for a layered feel */
  pointer-events: none;
}

/* --- Expand step 1: width grows to fill the menu-width column. --- */
.video-button-box.is-width-expanded {
  width: 100%;
  max-width: var(--menu-width);
}

/* --- Expand step 2: height creates the 16:9 video area.  Switch to a dark
   background so the video area looks intentional while the iframe loads. --- */
.video-button-box.is-height-expanded {
  height: 0;
  padding: 56.25% 0 0 0;   /* 16:9 aspect via padding-top trick */
  background: #000;
}
.video-button-box.is-height-expanded .video-button-box__text {
  opacity: 0;              /* text fades as height grows */
}

/* Cancel all idle animations the moment the box starts expanding. */
.video-button-box.is-width-expanded,
.video-button-box.is-height-expanded,
.video-button-box.is-video-visible {
  animation: none;
}
.video-button-box.is-width-expanded::after,
.video-button-box.is-height-expanded::after,
.video-button-box.is-video-visible::after {
  animation: none;
  opacity: 0;
  transition: opacity 200ms ease;
}

/* --- Button label (visible in the compact state). --- */
.video-button-box__text {
  color: #fff;
  font-size: 1rem;
  letter-spacing: var(--nav-letterspacing);
  white-space: nowrap;
  transition: opacity 300ms ease;
  position: relative;
  z-index: 2;
  pointer-events: none;    /* clicks pass through to the parent */
}

/* --- Expand step 3: the iframe wrapper fades in over the dark background. --- */
.video-button-box__video {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 400ms ease;
  pointer-events: none;
  z-index: 1;
}
.video-button-box.is-video-visible .video-button-box__video {
  opacity: 1;
  pointer-events: auto;
}
.video-button-box__video iframe {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}

/* Social icon row. Icons are white here (inherit .home color) and scale on hover. */
.social {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1.1rem;
}
.social-link {
  display: inline-flex;
  width: 44px; height: 44px;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  color: inherit;                          /* icon tint follows .home (white)       */
  /* Same frosted treatment as the menu bar: 50% black fill + backdrop blur, no border. */
  background: var(--menu-bg-home);
  backdrop-filter: blur(var(--menu-blur));
  -webkit-backdrop-filter: blur(var(--menu-blur));
  transition: transform 180ms var(--anim-ease), background 180ms var(--anim-ease);
}
.social-link:hover { transform: scale(1.18); background: rgba(0,0,0,0.65); }
.social-link__icon { width: 22px; height: 22px; }

/* ---------------------------------------------------------------------------
   6b. SITE FOOTER — admin-managed rich text at the bottom of EVERY public page
   (lib/partials/footer.php). Constrained to the shared content width and raised
   above the fixed HOME background. Muted on light pages; light on HOME's dark bg.
   --------------------------------------------------------------------------- */
.site-footer {
  position: relative;
  z-index: var(--z-content);
  width: 100%;
  max-width: var(--content-width);
  margin: 0 auto;
  padding: 1.25rem var(--gutter) 1.5rem;
  /* No divider line (per spec); it simply sits at the very bottom of the page. */
  color: var(--color-muted);
  text-align: center;
  font-size: 0.72rem;
}
.site-footer :first-child { margin-top: 0; }
.site-footer :last-child { margin-bottom: 0; }
.site-footer a { color: inherit; }

/* On HOME the footer overlays the dark background cycler → use light text + a faint
   divider so it stays readable. */
body.page-home .site-footer {
  color: rgba(255, 255, 255, 0.78);
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.5);
}

/* ---------------------------------------------------------------------------
   7. LINKS page — categorized rows of icons WITH text labels below
   (dark icons on light page). Each category is a heading + a centered row of links.
   --------------------------------------------------------------------------- */
.links {
  display: flex;
  flex-direction: column;
  gap: 2.5rem;
  padding-top: 1rem;
}
.links-cat__title {
  text-align: center;
  font-size: 0.95rem;
  letter-spacing: var(--nav-letterspacing);
  color: var(--color-muted);
  margin: 0 0 1.25rem;
  text-transform: uppercase;
}
.links-cat__items {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 2rem;
}
.link-item {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 0.6rem;
  text-decoration: none;
  color: var(--color-text);
  width: 120px;
  transition: transform 180ms var(--anim-ease);
}
.link-item:hover { transform: translateY(-4px); }
.link-item__icon {
  width: 64px; height: 64px;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--color-text);                /* tints the masked glyph — no disc, no border */
}
.link-item__glyph { width: 48px; height: 48px; }
.link-item__label { font-size: 0.8rem; letter-spacing: var(--nav-letterspacing); text-align: center; }

/* ---------------------------------------------------------------------------
   8. SIMPLE PAGE STUBS — gallery/commissions placeholders until their phases.
   --------------------------------------------------------------------------- */
.stub { text-align: center; color: var(--color-muted); padding: 3rem 0; }
.stub h1 { color: var(--color-text); letter-spacing: var(--nav-letterspacing); }

/* ---------------------------------------------------------------------------
   9. RESPONSIVE — stack the menu + reduce padding on narrow screens.
   On mobile the logo/key return to normal flow and everything stacks vertically.
   --------------------------------------------------------------------------- */
@media (max-width: 720px) {
  /* Single row that never stacks: logo, the nav links, and the key all sit on one
     line and simply shrink to fit. The logo + key leave their pinned (absolute)
     positions and flow inline, so the key sits right next to the last nav link
     rather than at the far edge. */
  .menu__island {
    flex-wrap: nowrap;
    justify-content: center;
    gap: 0.6rem;
    padding: 0.5rem var(--gutter);
  }
  .menu__logo, .menu__admin {
    position: static;
    transform: none;
    flex: 0 0 auto;      /* logo + key keep their size; the nav absorbs the squeeze */
  }
  .menu__admin:hover { transform: scale(1.1); }
  .menu__logo-icon { width: 96px; height: 22px; }
  .menu__nav {
    flex: 0 1 auto;      /* allowed to shrink so everything stays on one line */
    flex-wrap: nowrap;   /* never wrap to a second line */
    min-width: 0;
    gap: 0.7rem;
  }
  .menu__link { font-size: 0.72rem; white-space: nowrap; }
  .content { padding-top: 6rem; } /* back to a single-row menu → less clearance */
}

/* Very narrow (small phones): shrink the logo + nav further so the key still fits. */
@media (max-width: 440px) {
  .menu__island { gap: 0.4rem; }
  .menu__logo-icon { width: 78px; height: 18px; }
  .menu__nav { gap: 0.45rem; }
  .menu__link { font-size: 0.6rem; letter-spacing: 0.02em; }
}
