/* Shared styles for weiming.design.
   Most styling still lives inline on each page; this file holds what applies site-wide. */

/* ---------- Colours ----------
   The site's palette as named colours. Pages that use them switch to the dark palette when the
   visitor's device is set to dark mode. Pages marked class="dark-ready" switch (every page except the sample newsletter, which stays a light inbox mock-up). */
:root {
  --bg: #FFFFFF;
  --text: #222222;
  --muted: #5A5A63;
  --slate: #53656A;       /* name */
  --accent: #933E3E;      /* highlight red, and the sun mark */
  --linkedin: #0E76A8;
  --linkedin-hover: #0A5A82;
  --line: #E6E6E2;
  --tag-bg: #933E3E;      /* red section labels ("How I work") */
  --on-tag: #FFFFFF;      /* text on those labels */
  --placeholder: #EEEEEB; /* behind images while they load */
  --ph-backdrop: #E2E4E5; --sm-panel: #F2F2EF; --sm-card: #FFFFFF; --sm-line: #C9C9C2; --sm-line-soft: #DCDCD6; --sm-bar: #C9C9C2;  /* Design page sitemap */
}
.mark path { fill: var(--accent); }

/* Dark palette: a soft near-black page, warm off-white text, and the red, slate and blue lifted so they
   still read clearly on dark. Follows the device setting; .force-dark / .force-light override it. */
@media (prefers-color-scheme: dark) {
  html.dark-ready:not(.force-light) {
    --bg: #141414; --text: #EDEBE7; --muted: #A19D98; --slate: #98ACB2;
    --accent: #DD7F77; --linkedin: #5AAEDC; --linkedin-hover: #8CC7E8; --line: #2B2B2B;
    --tag-bg: #933E3E; --on-tag: #FFFFFF; --placeholder: #242424;
    --ph-backdrop: #1E1E1E; --sm-panel: #1E1E1E; --sm-card: #2A2A2A; --sm-line: #4C4C49; --sm-line-soft: #3A3A38; --sm-bar: #55554F;
    color-scheme: dark;
  }
}
html.dark-ready.force-dark {
  --bg: #141414; --text: #EDEBE7; --muted: #A19D98; --slate: #98ACB2;
  --accent: #DD7F77; --linkedin: #5AAEDC; --linkedin-hover: #8CC7E8; --line: #2B2B2B;
    --tag-bg: #933E3E; --on-tag: #FFFFFF; --placeholder: #242424;
    --ph-backdrop: #1E1E1E; --sm-panel: #1E1E1E; --sm-card: #2A2A2A; --sm-line: #4C4C49; --sm-line-soft: #3A3A38; --sm-bar: #55554F;
  color-scheme: dark;
}
html.dark-ready.force-light { color-scheme: light; }
html.dark-ready body { background: var(--bg); color: var(--text); }

/* ---------- Page width ----------
   Home, Contact and 404 counted the side padding inside their 1280px max width; the other
   pages added it on top. That made the short pages 96px narrower, so the menu sat 48px
   further in. Every page now measures the same way: 1280 of content + 48 padding each side. */
.wrap { box-sizing: border-box !important; max-width: 1376px !important; }

/* Footer: line the email and copyright up on their text baseline. On phones the email link
   has extra tap padding, which pushed its text 10px below the copyright line. */
.wrap footer { align-items: baseline; }

/* ---------- Phones and narrow windows (below 760) ----------
   The layout wraps the menu above the content. As a wrapping flex row inside a full-height
   page, the browser shared the spare height between the two rows, leaving a big gap under
   the menu on short pages. A column layout keeps the menu snug, and the content column
   takes up the spare height so the footer still sits at the bottom. */
@media (max-width: 759px) {
  .wrap { flex-direction: column !important; flex-wrap: nowrap !important; }
  .wrap > .side { flex: none !important; }
  .wrap > main { flex: 1 0 auto !important; }

  /* Menu as a balanced run of words: when it wraps, the rows even out (4+3, never 6+1),
     so no link is left on a row by itself. The gap comes from the spaces between links. */
  nav[aria-label="Main"] { display: block !important; text-wrap: balance; word-spacing: 13px; line-height: 1.12; }
  nav[aria-label="Main"] a { display: inline-block; word-spacing: normal; }
}

/* ---------- Wide screens ----------
   Matches the Figma wide-screen designs:
   1920: text ~1.32x desktop, page max 1800, content column 1100, menu-to-content gap 160.
   2560: the 1920 layout scaled up by a third (page max 2400, content column 1467).
   `zoom` scales the whole layout, so the inline px sizes scale with it. Widths below are
   written in pre-zoom pixels (target / zoom), e.g. 1800 / 1.32 = 1364. */

@media (min-width: 1920px) {
  .wrap {
    zoom: 1.32;
    max-width: 1364px !important;          /* 1800 on screen */
    min-height: calc(100vh / 1.32) !important;
    column-gap: 121px !important;          /* 160 on screen */
  }
  .wrap > main {
    max-width: 834px !important;           /* 1100 on screen */
    gap: 64px !important;                  /* extra breathing room: spacing ~1.45x vs text 1.32x */
  }
  .side { top: 48px !important; }        /* same as the page padding, so the menu doesn't jump when it sticks */
}

@media (min-width: 2560px) {
  .wrap {
    zoom: 1.76;                             /* 1.32 x 4/3 */
    min-height: calc(100vh / 1.76) !important;
    /* max-width 1364 x 1.76 = 2400, main 834 x 1.76 = 1467 on screen */
  }
}

/* Menu hover: the text turns the highlight red (LinkedIn deepens its own blue instead).
   A colour change isn't motion, so this applies for everyone, reduced motion included. */
@media (hover: hover) {
  nav[aria-label="Main"] a { transition: color 0.2s ease; }
  nav[aria-label="Main"] a:hover { color: var(--accent) !important; }
  nav[aria-label="Main"] a[href*="linkedin"]:hover { color: var(--linkedin-hover) !important; }
}

/* ---------- Animations ----------
   All motion lives inside this media query, so visitors who ask for reduced motion get none.
   The hidden starting states only apply once js/site.js has added the "anim" class. */
@media (prefers-reduced-motion: no-preference) {

  /* Plain fade in on scroll */
  .anim .reveal {
    opacity: 0;
    transition: opacity 0.8s ease;
    transition-delay: var(--d, 0ms);
  }
  .anim .reveal.in { opacity: 1; }

  /* Fade out when leaving a page: the content fades, the menu stays put */
  .anim.leaving main { opacity: 0 !important; transition: opacity 0.22s ease; }

  /* Photo page: each photo simply fades in as it scrolls into view. */
  .ph-frame { overflow: hidden; border-radius: 10px; }
  .ph-frame img { transition: transform 0.6s cubic-bezier(0.2, 0.7, 0.2, 1); }
  .anim .reveal-photo { opacity: 0; transition: opacity 0.9s ease; transition-delay: var(--d, 0ms); }
  .anim .reveal-photo.in { opacity: 1; }
  @media (hover: hover) {
    .ph-frame:hover img { transform: scale(1.04); }
  }

  /* Page transitions: the old page has already faded out (above), so the new one fades in,
     with the menu held still. Browsers without view transitions still get the fade out. */
  @view-transition { navigation: auto; }
  .side { view-transition-name: side-menu; }
  ::view-transition-old(root) { animation: 80ms ease both wm-fade-out; }
  ::view-transition-new(root) { animation: 320ms ease both wm-fade-in; }
  ::view-transition-group(side-menu) { animation-duration: 0s; }
  @keyframes wm-fade-out { to { opacity: 0; } }
  @keyframes wm-fade-in { from { opacity: 0; } }

  /* Hover effects (only on devices with a real pointer) */
  @media (hover: hover) {
    /* Writing: article links nudge their arrow and warm the title */
    main a[style*="border-top"] > span { transition: color 0.2s ease, transform 0.25s ease; }
    main a[style*="border-top"] > span:last-child { display: inline-block; align-self: flex-start; }
    main a[style*="border-top"]:hover > span:nth-child(2) { color: var(--accent) !important; }
    main a[style*="border-top"]:hover > span:last-child { transform: translate(4px, -2px); }

    /* Design: cards lift their image slightly */
    main > section:has(> h2) > img, main > section:has(> h2) > picture > img { transition: transform 0.35s cubic-bezier(0.2, 0.7, 0.2, 1), box-shadow 0.35s ease; }
    main > section:has(> h2):hover > img, main > section:has(> h2):hover > picture > img { transform: translateY(-4px); box-shadow: 0 14px 30px -18px rgba(34, 34, 34, 0.45); }

    /* Underlined text links ("Read the full story →") */
    main a { transition: color 0.2s ease; }
  }
}

@media print {
  .anim .reveal, .anim .reveal-photo { opacity: 1 !important; transform: none !important; }
}

/* ---------- Photo lightbox ----------
   Click a gallery photo to see it at full size. Dark backdrop in both colour modes. */
.gallery img { cursor: zoom-in; }
.lb { position: fixed; inset: 0; z-index: 100; display: flex; align-items: center; justify-content: center;
  background: rgba(12, 12, 12, 0.94); padding: 56px 72px; box-sizing: border-box; }
.lb[hidden] { display: none; }
.lb img { max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain; border-radius: 4px;
  box-shadow: 0 20px 60px -20px rgba(0, 0, 0, 0.7); user-select: none; -webkit-user-drag: none; }
.lb button { position: absolute; border: 0; background: transparent; color: #F2F2EF; cursor: pointer;
  font: 400 32px/1 'Inter Tight', system-ui, sans-serif; padding: 12px; opacity: 0.8; }
.lb button:hover, .lb button:focus-visible { opacity: 1; }
.lb button:focus-visible { outline: 2px solid #DD7F77; outline-offset: 2px; border-radius: 6px; }
.lb .lb-close { top: calc(10px + env(safe-area-inset-top, 0px)); right: calc(12px + env(safe-area-inset-right, 0px)); font-size: 36px; }
.lb .lb-prev { left: calc(8px + env(safe-area-inset-left, 0px)); top: 50%; transform: translateY(-50%); font-size: 40px; }
.lb .lb-next { right: calc(8px + env(safe-area-inset-right, 0px)); top: 50%; transform: translateY(-50%); font-size: 40px; }
.lb .lb-count { position: absolute; bottom: calc(16px + env(safe-area-inset-bottom, 0px)); left: 0; right: 0; text-align: center;
  color: #A19D98; font: 400 14px/1 'Inter Tight', system-ui, sans-serif; font-variant-numeric: tabular-nums; }
html.lb-open, html.lb-open body { overflow: hidden; }
@media (max-width: 759px) {
  .lb { padding: 56px 12px 48px; }
  .lb .lb-prev, .lb .lb-next { display: none; }   /* swipe instead */
}
@media (prefers-reduced-motion: no-preference) {
  .lb { animation: lb-in 0.2s ease both; }
  .lb img { animation: lb-in 0.25s ease both; }
  @keyframes lb-in { from { opacity: 0; } }
}

/* ---------- Spotify player (Writing page) ---------- */
.sp-frame { display: block; width: 100%; height: 352px; margin-top: 4px; border: 0; border-radius: 12px; background: var(--placeholder); }
