/* =========================================================================
   Picts by AI — AI image gallery
   Dark, glassy UI. Ported from the "AI image gallery design" comp.
   ========================================================================= */

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }

body {
  min-height: 100vh;
  overflow-x: hidden;
  background: #08080b;
  color: #f3f2f7;
  font-family: 'Manrope', sans-serif;
  -webkit-font-smoothing: antialiased;
}

::selection { background: rgba(183, 166, 255, 0.30); color: #fff; }

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.12); border-radius: 20px; }
::-webkit-scrollbar-track { background: transparent; }

/* --- Ambient background blobs ------------------------------------------- */
.bg {
  position: fixed;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
}
.blob {
  position: absolute;
  display: block;
  border-radius: 50%;
  filter: blur(30px);
}
.blob--a {
  top: -18%; left: -8%;
  width: 52vw; height: 52vw;
  background: radial-gradient(circle at center, rgba(124, 58, 237, 0.42), rgba(124, 58, 237, 0) 62%);
  animation: floatA 22s ease-in-out infinite;
}
.blob--b {
  top: 6%; right: -14%;
  width: 46vw; height: 46vw;
  background: radial-gradient(circle at center, rgba(219, 39, 119, 0.30), rgba(219, 39, 119, 0) 62%);
  animation: floatB 27s ease-in-out infinite;
}
.blob--c {
  bottom: -24%; left: 26%;
  width: 48vw; height: 48vw;
  background: radial-gradient(circle at center, rgba(14, 165, 233, 0.24), rgba(14, 165, 233, 0) 64%);
  filter: blur(36px);
  animation: floatA 30s ease-in-out infinite;
}

.page { position: relative; z-index: 1; }

/* --- Masthead ----------------------------------------------------------- */
.masthead {
  max-width: 820px;
  margin: 0 auto;
  padding: 84px 24px 40px;
  text-align: center;
}
.avatar {
  position: relative;
  /* Block-level, not inline-flex: as an inline box it sat on the masthead's
     text baseline, which added descender space under the circle on top of the
     margin below and left it looking detached from the name. */
  display: flex;
  margin: 0 auto;
  align-items: center;
  justify-content: center;
  width: 110px; height: 110px;
  border-radius: 50%;
  overflow: hidden;
  background: linear-gradient(145deg, #8b5cf6, #db2777 60%, #f59e0b);
  box-shadow: 0 8px 34px rgba(139, 92, 246, 0.42), inset 0 1px 1px rgba(255, 255, 255, 0.4);
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 700;
  font-size: 32px;
  letter-spacing: 0.5px;
  color: #fff;
}
.avatar__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.avatar__img[hidden] { display: none; }
.masthead__name {
  margin: 14px 0 0;
  font-family: 'Space Grotesk', sans-serif;
  font-weight: 600;
  font-size: 38px;
  letter-spacing: -0.5px;
  color: #faf9ff;
}
.masthead__handle {
  margin: 8px 0 0;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 13px;
  letter-spacing: 0.4px;
  color: rgba(243, 242, 247, 0.5);
}
.masthead__bio {
  margin: 16px auto 0;
  max-width: 440px;
  font-size: 15px;
  line-height: 1.6;
  color: rgba(243, 242, 247, 0.66);
}
.masthead__social {
  display: flex;
  gap: 12px;
  justify-content: center;
  flex-wrap: wrap;
  margin-top: 26px;
}
.masthead__count {
  margin: 34px 0 0;
  min-height: 1em;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 12px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: rgba(243, 242, 247, 0.34);
}

.pill {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 11px 20px;
  border-radius: 999px;
  text-decoration: none;
  color: #f3f2f7;
  font-size: 14px;
  font-weight: 600;
  background: rgba(255, 255, 255, 0.055);
  border: 1px solid rgba(255, 255, 255, 0.12);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.10);
  transition: background 0.22s ease, border-color 0.22s ease, transform 0.22s ease;
}
.pill:hover {
  background: rgba(255, 255, 255, 0.11);
  border-color: rgba(255, 255, 255, 0.22);
  transform: translateY(-2px);
}

.masthead:focus { outline: none; }

/* --- Gallery (balanced masonry columns) --------------------------------- */
.gallery {
  display: flex;
  gap: 18px;
  align-items: flex-start;
  max-width: 1440px;
  margin: 0 auto;
  padding: 8px 24px 56px;
}
.gallery__col {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.card {
  position: relative;
  overflow: hidden;
  cursor: pointer;
  border: 1px solid rgba(255, 255, 255, 0.09);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.34);
  transition: transform 0.28s cubic-bezier(0.2, 0.8, 0.2, 1), border-color 0.28s ease, box-shadow 0.28s ease;
}
.card:hover,
.card:focus-visible {
  transform: translateY(-5px);
  border-color: rgba(255, 255, 255, 0.26);
  box-shadow: 0 20px 44px rgba(0, 0, 0, 0.5);
  outline: none;
}
.card__media {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.card__overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-end;
  padding: 16px;
  background: linear-gradient(180deg, rgba(8, 8, 11, 0) 55%, rgba(8, 8, 11, 0.72));
  opacity: 0;
  transition: opacity 0.25s ease;
}
.card:hover .card__overlay,
.card:focus-visible .card__overlay { opacity: 1; }
.card__prompt {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 11.5px;
  letter-spacing: 0.3px;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.9);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.card__badges {
  position: absolute;
  top: 11px; right: 11px;
  display: flex;
  gap: 6px;
}
.card__badge {
  width: 30px; height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: rgba(12, 12, 16, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.16);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  color: #fff;
}

/* --- End of gallery ------------------------------------------------------
   Deliberately quieter than .pill: the masthead's three pills are the page's
   real calls to action, and an equally loud control down here would compete
   with them. So this borrows the pill's glass chrome but wears the meta
   typography of .masthead__count — both idioms already on the page, neither
   of them new.
   ------------------------------------------------------------------------- */
.pagefoot {
  display: flex;
  justify-content: center;
  padding: 0 24px 104px;
}
.totop {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;                    /* tap target on phones */
  padding: 0 22px;
  border-radius: 999px;
  text-decoration: none;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 12px;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: rgba(243, 242, 247, 0.42);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.10);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.07);
  transition: background 0.22s ease, border-color 0.22s ease,
              color 0.22s ease, transform 0.22s ease;
}
.totop:hover {
  color: #f3f2f7;
  background: rgba(255, 255, 255, 0.10);
  border-color: rgba(255, 255, 255, 0.22);
  transform: translateY(-2px);
}
.totop:focus-visible {
  outline: 2px solid rgba(183, 166, 255, 0.75);
  outline-offset: 3px;
}
/* The arrow lifts a little further than the link does, so the gesture reads
   as "up" rather than as a generic hover state. */
.totop svg { transition: transform 0.22s ease; }
.totop:hover svg { transform: translateY(-2px); }

/* --- In-flight (back to top) --------------------------------------------
   The flight is a real scroll across the whole page now, so these rules cover
   seconds of continuous motion rather than a final glide. Measured, the
   scroll holds 60fps without them; they are kept as headroom for slower
   machines than this one, and they cost nothing while the page is moving.
   None of them is perceptible while the page is moving, and all are restored
   the instant it stops:

     • 402 badge backdrop-filters. Each forces the compositor to snapshot the
       region behind it and blur it — by far the most expensive thing here.
     • Card hover transitions. The cursor sits still while the page moves under
       it, so every card sweeping past fires translateY + a 44px-blur
       box-shadow. Killing pointer-events stops that at the source, and it
       still matters at two screens' worth of cards.
     • The blobs, whose scale() keyframes re-rasterize a 30px blur per frame.

   The resting box-shadow is deliberately left alone. Suppressing it does save
   paint, but .card transitions box-shadow, so restoring it faded every visible
   card back in over 280ms at the end of each flight — a worse artefact than
   the cost it removed.
   ------------------------------------------------------------------------- */
body.is-flying .gallery { pointer-events: none; }
body.is-flying .card { transition: none; }
body.is-flying .card__overlay {
  transition: none;
  opacity: 0;
}
body.is-flying .card__badge {
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
}
body.is-flying .blob { animation-play-state: paused; }

/* --- Lightbox ----------------------------------------------------------- */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 28px;
  background: rgba(6, 6, 9, 0.68);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  animation: ovIn 0.25s ease;
}
.lightbox[hidden] { display: none; }

.nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 48px; height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.14);
  background: rgba(255, 255, 255, 0.06);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  color: #fff;
  font-size: 20px;
  cursor: pointer;
  transition: background 0.2s ease;
}
.nav:hover { background: rgba(255, 255, 255, 0.14); }
.nav--prev { left: 20px; }
.nav--next { right: 20px; }

/* Width and height are set inline by gallery.js from the image's real pixel
   dimensions (see sizePanel), so the image fills the hero exactly instead of
   being letterboxed inside a fixed-proportion column. The caps below are a
   safety net for the stacked layout and for before the first sizing runs. */
.lightbox__panel {
  position: relative;
  display: flex;
  flex-wrap: nowrap;
  align-items: stretch;
  max-width: 1080px;
  max-height: 86vh;
  border-radius: 28px;
  overflow: hidden;
  background: rgba(20, 20, 26, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.14);
  backdrop-filter: blur(30px);
  -webkit-backdrop-filter: blur(30px);
  box-shadow: 0 30px 90px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.10);
  animation: lbIn 0.3s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.lightbox__close {
  position: absolute;
  top: 16px; right: 16px;
  z-index: 2;
  width: 38px; height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.16);
  background: rgba(12, 12, 16, 0.4);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  color: #fff;
  font-size: 17px;
  cursor: pointer;
  transition: background 0.2s ease;
}
.lightbox__close:hover { background: rgba(255, 255, 255, 0.16); }

.lightbox__hero {
  flex: 0 0 auto;              /* width comes from JS, not from flex negotiation */
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  background: #0a0a0d;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
}
/* The hero box is built from the image's true aspect ratio, so filling it edge
   to edge neither crops nor letterboxes — the two are the same shape. */
.lightbox__hero-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.lightbox__hero-img[hidden] { display: none; }
.lightbox__info {
  flex: 1 1 auto;
  min-width: 0;
  min-height: 0;               /* required for overflow-y to scroll in a flex row */
  padding: 34px 32px;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
}
.lightbox__label {
  margin: 0;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 11px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: rgba(243, 242, 247, 0.4);
}
.lightbox__prompt {
  margin: 16px 0 0;
  font-family: 'IBM Plex Mono', monospace;
  font-size: 14.5px;
  line-height: 1.72;
  color: #eeedf4;
  white-space: pre-wrap;
}
.lightbox__spacer { flex: 1; min-height: 24px; }
.lightbox__actions {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-top: 28px;
}
.lightbox__links {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  padding: 14px 20px;
  border-radius: 999px;
  font-family: 'Manrope', sans-serif;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
}
.btn__icon { display: inline-flex; }
.btn--copy {
  border: 1px solid rgba(255, 255, 255, 0.14);
  color: #0a0a0c;
  background: linear-gradient(145deg, #e9e3ff, #c9bbff);
  box-shadow: 0 6px 20px rgba(183, 166, 255, 0.28);
  transition: filter 0.2s ease, background 0.25s ease;
}
.btn--copy:hover { filter: brightness(1.08); }
.btn--copy.is-copied { background: linear-gradient(145deg, #86efac, #4ade80); }
.btn--ghost {
  color: #f3f2f7;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.13);
  transition: background 0.2s ease;
}
.btn--ghost:hover { background: rgba(255, 255, 255, 0.1); }

/* --- Identity-reference switch ------------------------------------------ */
/* The snippet appended to a prompt when the switch is on. It is rendered as a
   span inside .lightbox__prompt, which is pre-wrap, so the blank line before
   it is a literal "\n\n" text node rather than a margin. */
.lightbox__addon { color: #c9bbff; }

.addon { display: flex; flex-direction: column; gap: 8px; }
.switch {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  padding: 4px 0;
  border: 0;
  background: none;
  cursor: pointer;
  font-family: 'Manrope', sans-serif;
  font-size: 13.5px;
  font-weight: 600;
  color: rgba(243, 242, 247, 0.72);
  text-align: left;
  transition: color 0.2s ease;
}
.switch:hover { color: #f3f2f7; }
.switch:focus-visible {
  outline: 2px solid #c9bbff;
  outline-offset: 3px;
  border-radius: 8px;
}
.switch__track {
  flex: none;
  position: relative;
  width: 38px; height: 21px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.11);
  border: 1px solid rgba(255, 255, 255, 0.16);
  transition: background 0.22s ease, border-color 0.22s ease;
}
.switch__knob {
  position: absolute;
  top: 50%; left: 3px;
  width: 15px; height: 15px;
  margin-top: -7.5px;
  border-radius: 50%;
  background: rgba(243, 242, 247, 0.75);
  transition: transform 0.22s ease, background 0.22s ease;
}
.switch[aria-checked="true"] { color: #f3f2f7; }
.switch[aria-checked="true"] .switch__track {
  background: linear-gradient(145deg, #e9e3ff, #c9bbff);
  border-color: transparent;
}
.switch[aria-checked="true"] .switch__knob {
  transform: translateX(15px);
  background: #0a0a0c;
}
.addon__hint {
  margin: 0;
  padding-left: 49px;          /* aligns under the label, clear of the track */
  font-size: 12px;
  line-height: 1.5;
  color: rgba(243, 242, 247, 0.45);
}
.addon__hint[hidden] { display: none; }
.addon[hidden] { display: none; }

/* --- Lightbox: small screens -------------------------------------------- */
@media (max-width: 720px) {
  .lightbox { padding: 14px; }
  .lightbox__panel {
    flex-direction: column;
    flex-wrap: nowrap;
    max-height: 92vh;
    overflow-y: auto;
  }
  /* Stacked: the image goes full width at its own aspect ratio and the panel
     scrolls, so nothing is letterboxed on a phone either. gallery.js clears the
     inline width/height here and sets aspect-ratio on the hero instead. */
  .lightbox__hero {
    flex: none;
    width: 100%;
  }
  .lightbox__info {
    flex: none;
    min-height: auto;
    overflow-y: visible;
    padding: 24px;
  }
  .switch { padding: 11px 0; min-height: 44px; }        /* 44px tap target */
  .addon__hint { padding-left: 0; }
  .nav { width: 42px; height: 42px; }
  .nav--prev { left: 8px; }
  .nav--next { right: 8px; }
}

/* --- Keyframes ---------------------------------------------------------- */
@keyframes floatA {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(7%, -5%) scale(1.12); }
}
@keyframes floatB {
  0%, 100% { transform: translate(0, 0) scale(1); }
  50% { transform: translate(-6%, 6%) scale(1.18); }
}
@keyframes lbIn {
  from { opacity: 0; transform: scale(0.965) translateY(8px); }
  to { opacity: 1; transform: scale(1) translateY(0); }
}
@keyframes ovIn {
  from { opacity: 0; }
  to { opacity: 1; }
}

/* Respect users who prefer reduced motion */
@media (prefers-reduced-motion: reduce) {
  .blob { animation: none; }
  .lightbox, .lightbox__panel { animation: none; }
  .card, .pill, .nav, .btn, .lightbox__close, .card__overlay,
  .switch, .switch__track, .switch__knob,
  .totop, .totop svg { transition: none; }
  .totop:hover, .totop:hover svg { transform: none; }
}
