/* aires.graphics styles
   1. Tokens       5. Home page       9. Footer
   2. Base         6. Glass slider   10. Motion & accessibility
   3. Header       7. Experience page
   4. Transitions  8. Contact page */


/* ---------- 1. Tokens ---------- */
/* Each color is light-dark(light, dark). The page follows the system theme, unless the
   theme toggle sets data-theme="light" or "dark" on <html>. */
:root { color-scheme: light dark; }
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"] { color-scheme: dark; }
:root {
  --bg: light-dark(#ffffff, #0f0f0f);
  --text: light-dark(#111111, #ededed);
  --text-secondary: light-dark(#757575, #8f8f8f);
  --focus: light-dark(#2f6fea, #6b9bff);
  --media-bg: light-dark(#f1f1f1, #1c1c1c);
  --border: light-dark(#ebebeb, #262626);
  --line: light-dark(rgba(0, 0, 0, .05), rgba(255, 255, 255, .08));
  --glass-line: light-dark(rgba(17, 17, 17, .06), rgba(255, 255, 255, .08));
  --shadow: light-dark(rgba(0, 0, 0, .08), rgba(0, 0, 0, .45));
  --lens-bg: light-dark(#ffffff, #2a2a2a);
  --lens-glow: light-dark(rgba(255, 255, 255, .9), rgba(255, 255, 255, .06));
  --hairline: 1px solid var(--line);
  --glass: color-mix(in srgb, var(--bg) 65%, transparent);
  --glass-border: 1px solid var(--glass-line);
  --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;
  --text-base: .9375rem; /* 15px — the only type size on the page */
  --max-width: 1440px;
  --gutter: clamp(20px, 4vw, 48px);
  --grid-gap: 8px;
  --section-gap: clamp(112px, 16vh, 208px);
  --radius: 8px;
  --ease-out: cubic-bezier(.22, 1, .36, 1);
}


/* ---------- 2. Base ---------- */
* { box-sizing: border-box; }
/* Anything marked hidden stays hidden, even if its own rules set a display */
[hidden] { display: none !important; }
html { scroll-behavior: smooth; }
body {
  margin: 0; min-height: 100vh; display: flex; flex-direction: column;
  background: var(--bg); color: var(--text);
  font-family: var(--font-sans); font-size: var(--text-base); line-height: 1.55;
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
}
p { text-wrap: pretty; }
h1, h2 { text-wrap: balance; }
a { color: inherit; text-decoration: none; }
a[target=_blank] { text-decoration: underline dotted 1px; text-underline-offset: .2em; }
a[target=_blank]::after { content: " ↗"; }
img, video { display: block; max-width: 100%; height: auto; }
/* One focus ring for every link and button, shown only for keyboard users */
:where(a, button):focus { outline: none; }
:where(a, button):focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: 4px; }
.container { max-width: var(--max-width); margin-inline: auto; padding-inline: var(--gutter); }
.skip-link {
  position: absolute; left: var(--gutter); top: -100%; z-index: 30;
  padding: 8px 12px; background: var(--text); color: var(--bg); border-radius: var(--radius);
}
.skip-link:focus { top: 12px; }
main { width: 100%; flex: 1; padding-block-start: 88px; }
/* Lenis smooth scroll (home page) */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }


/* ---------- 3. Header ---------- */
/* The header gets its own view-transition layer, so it holds still while pages cross-fade */
.site-header {
  position: fixed; top: 14px; inset-inline: 0; z-index: 20;
  display: flex; justify-content: center; gap: 8px; pointer-events: none;
  view-transition-name: site-header;
}

/* Floating glass nav: hides after a long scroll down (js/home.js), returns on scroll up */
.floating-nav {
  pointer-events: auto; display: flex; align-items: baseline; gap: 22px;
  padding: 12px 22px; border-radius: 999px;
  background: var(--glass); border: var(--glass-border);
  backdrop-filter: blur(24px) saturate(1.4); -webkit-backdrop-filter: blur(24px) saturate(1.4);
  transition: transform .38s var(--ease-out), opacity .38s ease;
}
.floating-nav.is-hidden { transform: translateY(-180%); opacity: 0; transition-delay: .18s; }
.floating-nav.is-hidden:focus-within { transform: none; opacity: 1; }
.floating-nav a { color: var(--text-secondary); white-space: nowrap; transition: color .12s ease; }
.floating-nav a:hover, .floating-nav a:focus-visible, .floating-nav a[aria-current=page] { color: var(--text); }

/* Theme toggle (js/theme-toggle.js): a round glass button that hides and shows with the nav */
.theme-toggle {
  pointer-events: auto; display: grid; place-items: center; flex: none;
  width: 49px; height: 49px; padding: 0; border-radius: 999px; cursor: pointer;
  color: var(--text-secondary); background: var(--glass); border: var(--glass-border);
  backdrop-filter: blur(24px) saturate(1.4); -webkit-backdrop-filter: blur(24px) saturate(1.4);
  transition: transform .38s var(--ease-out), opacity .38s ease, color .12s ease;
}
.theme-toggle:hover { color: var(--text); }
.theme-toggle:focus-visible { border-radius: 999px; }
.theme-toggle svg { display: block; }
.floating-nav.is-hidden + .theme-toggle { transform: translateY(-180%); opacity: 0; transition-delay: .18s; }
.floating-nav.is-hidden + .theme-toggle:focus-visible { transform: none; opacity: 1; }
/* Moon in the light theme, sun in the dark one */
.theme-toggle .sun { display: none; }
:root[data-theme="dark"] .theme-toggle .sun { display: block; }
:root[data-theme="dark"] .theme-toggle .moon { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .theme-toggle .sun { display: block; }
  :root:not([data-theme="light"]) .theme-toggle .moon { display: none; }
}

/* Small screens (js/nav-menu.js): the nav folds into a menu button (page name + ☰) with a dropdown */
.menu-toggle { display: none; }
@media (max-width: 480px) {
  .menu-toggle {
    pointer-events: auto; display: flex; align-items: center; gap: 12px;
    height: 49px; padding: 0 20px 0 22px; border-radius: 999px; cursor: pointer;
    font: inherit; color: var(--text); background: var(--glass); border: var(--glass-border);
    backdrop-filter: blur(24px) saturate(1.4); -webkit-backdrop-filter: blur(24px) saturate(1.4);
    transition: transform .38s var(--ease-out), opacity .38s ease;
  }
  .menu-toggle:focus-visible { border-radius: 999px; }
  /* Two bars that turn into an ✕ when the menu is open */
  .menu-icon { position: relative; width: 16px; height: 10px; }
  .menu-icon::before, .menu-icon::after {
    content: ""; position: absolute; left: 0; right: 0; height: 1.5px; border-radius: 1px;
    background: currentColor; transition: transform .3s var(--ease-out), top .3s var(--ease-out);
  }
  .menu-icon::before { top: 0; }
  .menu-icon::after { top: 8.5px; }
  .menu-open .menu-icon::before { top: 4.25px; transform: rotate(45deg); }
  .menu-open .menu-icon::after { top: 4.25px; transform: rotate(-45deg); }

  /* The nav becomes the dropdown, hidden until the menu opens */
  .floating-nav {
    position: absolute; top: 57px; left: 50%; translate: -50% 0;
    flex-direction: column; align-items: stretch; gap: 2px; min-width: 220px;
    padding: 6px; border-radius: 20px;
    /* More solid than the bar, so the links stay readable over photos */
    background: color-mix(in srgb, var(--bg) 90%, transparent);
    opacity: 0; visibility: hidden; transform: translateY(-8px) scale(.97); transform-origin: top center;
    transition: opacity .2s ease, transform .3s var(--ease-out), visibility 0s linear .3s;
  }
  .floating-nav a { padding: 11px 16px; border-radius: 14px; }
  .floating-nav a[aria-current=page] { background: var(--media-bg); }
  .floating-nav a:focus-visible { border-radius: 14px; }
  .menu-open .floating-nav { opacity: 1; visibility: visible; transform: none; transition-delay: 0s; }
  /* Picking a link closes the menu instantly, so the page cross-fade doesn't catch it half-faded */
  .menu-instant .floating-nav, .menu-instant .menu-icon::before, .menu-instant .menu-icon::after { transition: none; }

  /* The bar hides and shows with scrolling, like the full nav */
  .site-header:has(.floating-nav.is-hidden) .menu-toggle { transform: translateY(-180%); opacity: 0; transition-delay: .18s; }
  .site-header:has(.floating-nav.is-hidden) .menu-toggle:focus-visible { transform: none; opacity: 1; }
}

/* Scroll edge: content softly blurs and fades as it slides under the header */
.scroll-edge { position: fixed; inset: 0 0 auto; height: 104px; z-index: 15; pointer-events: none; }
.scroll-edge span { position: absolute; inset: 0; }
.scroll-edge span:nth-child(1) { backdrop-filter: blur(1px); -webkit-backdrop-filter: blur(1px); mask: linear-gradient(#000 0 55%, transparent 100%); -webkit-mask: linear-gradient(#000 0 55%, transparent 100%); }
.scroll-edge span:nth-child(2) { backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px); mask: linear-gradient(#000 0 35%, transparent 75%); -webkit-mask: linear-gradient(#000 0 35%, transparent 75%); }
.scroll-edge span:nth-child(3) { backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); mask: linear-gradient(#000 0 18%, transparent 52%); -webkit-mask: linear-gradient(#000 0 18%, transparent 52%); }
.scroll-edge span:nth-child(4) { backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); mask: linear-gradient(#000 0 4%, transparent 30%); -webkit-mask: linear-gradient(#000 0 4%, transparent 30%); }
.scroll-edge::after { content: ""; position: absolute; inset: 0; background: linear-gradient(var(--bg) 0%, color-mix(in srgb, var(--bg) 70%, transparent) 35%, transparent 100%); }


/* ---------- 4. Transitions ---------- */
/* Moving between pages cross-fades instead of flashing (where supported) */
@view-transition { navigation: auto; }
/* Page and theme cross-fades, and the theme icon turning into place */
::view-transition-old(root), ::view-transition-new(root) { animation-duration: .5s; animation-timing-function: var(--ease-out); }
.theme-toggle.is-switching svg { animation: icon-turn .5s var(--ease-out); }
@keyframes icon-turn { from { opacity: 0; transform: rotate(-90deg) scale(.6); } }


/* ---------- 5. Home page ---------- */
/* Intro */
.page-intro { margin-block: clamp(48px, 9vh, 120px) 0; max-width: 56ch; }
.avatar {
  width: 64px; height: 64px; border-radius: 50%; margin-block-end: 24px;
  background: var(--media-bg); object-fit: cover;
}
h1 { font-size: inherit; font-weight: 600; margin: 0; }
.role { color: var(--text-secondary); margin: 0; }
.bio { margin-block: 20px 0; }
.work-rule { border: 0; border-top: var(--hairline); margin-block: 64px 0; }

/* Upcoming work: shown while the projects are being written; the three dots pulse in turn */
.upcoming { margin-block: 40px var(--section-gap); }
.upcoming-label { margin: 0; color: var(--text-secondary); }
.dots span { animation: dot-pulse 1.4s ease-in-out infinite; }
.dots span:nth-child(2) { animation-delay: .2s; }
.dots span:nth-child(3) { animation-delay: .4s; }
@keyframes dot-pulse { 0%, 60%, 100% { opacity: .25; } 30% { opacity: 1; } }

/* Filter pills (the glass pill on top comes from section 6) */
.filters {
  position: relative; display: flex; flex-wrap: wrap; gap: 4px; margin-block: 10px 40px;
  user-select: none; -webkit-user-select: none; touch-action: pan-y;
}
.filters button {
  position: relative; z-index: 1;
  font: inherit; color: var(--text); background: transparent; border: 0;
  padding: 6px 16px; border-radius: 999px; cursor: pointer;
}
/* Phones keep :hover after a tap, so only real hover devices get the hover background */
@media (hover: hover) {
  .filters button:hover { background: color-mix(in srgb, var(--media-bg) 55%, transparent); }
}
.filters button[aria-pressed=true] { background: var(--media-bg); }
.filters.has-indicator button[aria-pressed=true] { background: transparent; }
/* Draw the focused filter's ring above the glass pill */
.filters button:focus-visible { z-index: 3; }

/* Projects */
.project { margin-block-end: var(--section-gap); }
.intro { margin-block-end: 26px; }
.project h2 { font-size: var(--text-base); font-weight: 600; margin: 0 0 10px; }
.context { color: var(--text-secondary); font-weight: 400; }
.description, .row-note { max-width: 56ch; }
.description p { margin: 0 0 .75em; }
.description p:last-child { margin-bottom: 0; }
.row-note { margin-block: 64px 26px; }

/* Media rows: each cell's flex-grow is its aspect ratio (set by js/home.js), so a row's images share one height */
.media-row { display: flex; align-items: stretch; gap: var(--grid-gap); }
.media-row + .media-row { margin-block-start: var(--grid-gap); }
.cell { flex: 0 1 0%; min-width: 0; }
.media { margin: 0; height: 100%; will-change: transform; }
.media img, .media video, .placeholder {
  display: block; width: 100%; height: 100%; object-fit: cover;
  border-radius: var(--radius); background: var(--media-bg);
  outline: var(--hairline); outline-offset: -1px;
}
.placeholder {
  display: grid; place-items: center; color: var(--text-secondary);
  aspect-ratio: var(--ph-aspect);
}
@media (max-width: 768px) {
  .media-row { flex-direction: column; }
  .cell { flex: none !important; }
}

/* Scroll cue: a bobbing arrow that fades once the visitor scrolls */
.scroll-cue {
  position: fixed; bottom: 22px; inset-inline: 0; margin-inline: auto; width: fit-content; z-index: 10;
  padding: 11px 26px; display: grid; place-items: center; pointer-events: none;
  background: var(--glass); border: var(--glass-border); border-radius: 999px;
  backdrop-filter: blur(24px) saturate(1.4); -webkit-backdrop-filter: blur(24px) saturate(1.4);
  box-shadow: 0 6px 24px var(--shadow);
  animation: cue-bob 1.8s ease-in-out infinite; transition: opacity .5s ease;
}
.scroll-cue.is-done { opacity: 0; }
@keyframes cue-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(6px); } }


/* ---------- 6. Glass slider ---------- */
/* js/glass-slider.js: a pill that carries its own copy of the options. While it moves it turns
   into a glass lens that bends that copy (js/liquid-glass.js), so it works in every browser.
   Leaving the lens fades slowly back to rest; entering it is quicker. */
.glass-indicator {
  position: absolute; top: 0; left: 0; z-index: 2; pointer-events: none;
  border-radius: 999px; transition: box-shadow .5s var(--ease-out);
}
/* clip (not hidden) so nothing, like find-in-page or scrollIntoView, can scroll the copy out of line */
.glass-lens {
  position: absolute; inset: 0; overflow: hidden; overflow: clip; border-radius: inherit;
  background: var(--media-bg); transition: background-color .5s var(--ease-out), box-shadow .5s var(--ease-out);
}
.glass-copy { position: absolute; top: 0; left: 0; }
.glass-indicator.is-lens { transition-duration: .2s; box-shadow: 0 0 0 .5px var(--glass-line), 0 6px 16px var(--shadow); }
.glass-indicator.is-lens .glass-lens { transition-duration: .2s; background: var(--lens-bg); box-shadow: inset 0 0 10px var(--lens-glow), inset 0 1px 2px var(--lens-glow); }


/* ---------- 7. Experience page ---------- */
.page { margin-block: clamp(48px, 9vh, 120px); min-height: 50vh; }
.page section + section { margin-block-start: 72px; }
/* Section label sitting on a full-width hairline divider */
.page h2 {
  font-size: var(--text-base); font-weight: 500; color: var(--text-secondary);
  margin: 0 0 24px; padding-block-end: 12px; border-bottom: var(--hairline);
}
.timeline { list-style: none; margin: 0; padding: 0; display: grid; gap: 32px; }
.timeline li { display: grid; grid-template-columns: 112px 1fr; gap: 16px; align-items: baseline; }
.timeline .dates { color: var(--text-secondary); font-variant-numeric: tabular-nums; }
.timeline .head { margin: 0; }
.timeline .head strong { font-weight: 600; }
.timeline .subrole { margin: 4px 0 0; }
.timeline .role { color: var(--text-secondary); }
.timeline .note { margin: 8px 0 0; max-width: 56ch; }
@media (max-width: 600px) {
  .timeline li { grid-template-columns: 1fr; gap: 2px; }
}


/* ---------- 8. Contact page ---------- */
.contact { margin-block: clamp(48px, 9vh, 120px); min-height: 50vh; }
.contact .lede { max-width: 44ch; margin: 0 0 40px; }
.contact-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.contact-list a { text-decoration: underline dotted 1px; text-underline-offset: .2em; }


/* ---------- 9. Footer ---------- */
footer { width: 100%; padding-block: 40px 56px; color: var(--text-secondary); }
footer p { margin: 0; }


/* ---------- 10. Motion & accessibility ---------- */
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
  html { scroll-behavior: auto; }
  .floating-nav { transition: opacity .2s ease; }
  .floating-nav.is-hidden { transform: none; }
  .theme-toggle { transition: opacity .2s ease, color .12s ease; }
  .floating-nav.is-hidden + .theme-toggle { transform: none; }
  .menu-toggle, .floating-nav, .menu-icon::before, .menu-icon::after { transition-duration: .01s; }
  .site-header:has(.floating-nav.is-hidden) .menu-toggle { transform: none; }
  .dots span { animation: none; opacity: 1; }
  .scroll-cue { animation: none; }
}
@media (prefers-reduced-transparency: reduce) {
  .scroll-edge { display: none; }
}
