/* ================================================================
   GalSol — Prime Site  |  prime-site.css

   Loaded AFTER gal-studio.css, which supplies the shared shell:
   .gal-shell / .gal-rail / .gal-main / .gal-welcome / .gal-box /
   .gal-pills / .gal-account. This file only carries what Prime Site
   does differently. Anything reused keeps its .gal-* class so the two
   surfaces stay visually identical for free.

   Prime-Site-only additions are prefixed .ps-.
================================================================ */

/* ── Platform chrome ───────────────────────────────────────────────
   The GalSol scrollbar (same as the editor and every other tool) — this
   page was falling back to the OS default. */
* { scrollbar-width: thin; scrollbar-color: rgba(0, 212, 255, .32) transparent; }
*::-webkit-scrollbar { width: 9px; height: 9px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: linear-gradient(180deg, rgba(0, 212, 255, .4), rgba(124, 58, 237, .4));
  border-radius: 20px; border: 2px solid transparent; background-clip: padding-box;
}
*::-webkit-scrollbar-thumb:hover { background: linear-gradient(180deg, rgba(0, 212, 255, .65), rgba(124, 58, 237, .65)); background-clip: padding-box; }

/* Kill the browser's blue focus ring on controls. Keyboard users still get a
   ring via :focus-visible — removing focus outlines outright is a real a11y
   regression, so only the mouse-click ring goes. */
button:focus, a:focus, input:focus, textarea:focus, [role="button"]:focus { outline: none; }
button:focus-visible, a:focus-visible, input:focus-visible, textarea:focus-visible {
  outline: 2px solid rgba(0, 212, 255, .55); outline-offset: 2px;
}

/* ── Background: the DotField layer ────────────────────────────────
   The swappable background is the React-Bits DotField (dotfield.js), a
   canvas grid of dots that bulge away from the cursor. Behind it sits a
   smooth animated brand gradient (below). The dot canvas is transparent
   between dots, so the gradient shows through. Whole layer is behind
   .gal-shell (z-index:1). */
.ps-bg {
  position: fixed; inset: 0; z-index: 0; pointer-events: none; overflow: hidden;
  background: var(--gal-bg);   /* brand near-black — never pure #000 */
  opacity: 1; transition: opacity 1.2s ease;
}
/* Smooth animated brand gradient, BEHIND the dot canvas (z-index 0 vs the
   canvas's 1). Two soft blobs ORBIT on a linear-infinite loop — rotate →
   translate → counter-rotate traces a perfect circle, so the motion is
   continuous and seamless (no ease-in-out bounce at the ends = properly
   smooth). blur keeps the edges buttery. */
.ps-bg::before, .ps-bg::after {
  content: ''; position: absolute; border-radius: 50%; z-index: 0;
  pointer-events: none; will-change: transform; filter: blur(46px);
}
.ps-bg::before {
  width: 66vw; height: 66vw; left: -8%; top: -14%;
  background: radial-gradient(closest-side, rgba(0, 212, 255, 0.22), transparent 72%);
  animation: psOrbitA 42s linear infinite;
}
.ps-bg::after {
  width: 60vw; height: 60vw; right: -10%; bottom: -16%;
  background: radial-gradient(closest-side, rgba(124, 58, 237, 0.26), transparent 72%);
  animation: psOrbitB 54s linear infinite;
}
@keyframes psOrbitA {
  from { transform: rotate(0deg)   translate(7%, 4%)  rotate(0deg); }
  to   { transform: rotate(360deg) translate(7%, 4%)  rotate(-360deg); }
}
@keyframes psOrbitB {
  from { transform: rotate(0deg)    translate(-6%, -4%) rotate(0deg); }
  to   { transform: rotate(-360deg) translate(-6%, -4%) rotate(360deg); }
}
/* the dot canvas sits on TOP of the gradient. opacity < 1 dims the dots very
   slightly so they read as texture, not a bright grid. */
.ps-bg canvas, .ps-bg svg { position: absolute; inset: 0; z-index: 1; }
.ps-bg canvas { opacity: 0.9; }

/* The composer must read clearly over the busy dot field — a stronger frost
   than the shared default (which was tuned for GAL Studio's calm aurora). */
.gal-box {
  background: linear-gradient(180deg, rgba(255,255,255,.05), rgba(255,255,255,.012)), rgba(12, 14, 22, 0.72) !important;
  -webkit-backdrop-filter: blur(26px) saturate(150%) !important;
  backdrop-filter: blur(26px) saturate(150%) !important;
}
/* consistency with the old aurora: gentle dim if a chat ever starts */
body.gal-started .ps-bg { opacity: 0.55; }
@media (prefers-reduced-motion: reduce) {
  .ps-bg::before, .ps-bg::after { animation: none; }
}

/* ── Landing = Create New ──────────────────────────────────────────
   The composer AND the recent-projects shelf must both be on the first
   screen — the shelf used to sit below the fold where nobody found it.
   So: .gal-main is a viewport-height column, .ps-stage takes whatever
   space is left over (centring the composer inside it), and the shelf
   keeps its natural height at the bottom. The composer therefore rides
   slightly above true centre, which is exactly the intent. */
.gal-main { overflow-y: auto; overflow-x: hidden; }
body.gal-idle .gal-main { justify-content: flex-start; }
.ps-stage {
  flex: 1 1 auto; min-height: 300px;      /* never let the composer be crushed */
  display: flex; flex-direction: column; justify-content: center;
  padding: 20px 0 6px;
}
/* Expanded, the shelf owns the screen and the stage yields. */
body.ps-shelf-open .ps-stage { flex: 0 0 auto; min-height: 0; }

/* The hint is hidden while idle in GAL Studio (it only matters mid-chat).
   Here idle IS the page, so it's the one line of guidance we always show. */
body.gal-idle .gal-composer-hint { display: block; }

/* ── Welcome ───────────────────────────────────────────────────────
   Violet drop-shadow instead of GAL's cyan — matches prime-site.svg. */
.gal-welcome-mark { filter: drop-shadow(0 6px 24px rgba(124, 58, 237, .40)); }

/* ── GitHub chip (connected state, Create New only) ────────────────
   Slim + non-blocking: once GitHub is connected it should be reassurance,
   not furniture. Fixed (not absolute) because .gal-main is the scroll
   container here — absolute would scroll away with the recents. It sits
   below .gal-library's z-index so the overlay covers it. */
.ps-ghchip {
  position: fixed; top: 14px; right: 18px; z-index: 6;
  display: none; align-items: center; gap: 7px;
  padding: 6px 11px; border-radius: 999px;
  background: var(--gal-panel); border: 1px solid var(--gal-border);
  font-size: 12px; font-weight: 500; color: var(--gal-text-dim);
  text-decoration: none; transition: border-color .15s, color .15s;
}
.ps-ghchip.on { display: inline-flex; }
.ps-ghchip:hover { border-color: var(--gal-border-2); color: var(--gal-text); }
.ps-ghchip svg { width: 13px; height: 13px; flex-shrink: 0; }
.ps-ghdot { width: 6px; height: 6px; border-radius: 50%; background: var(--gal-ok); flex-shrink: 0; box-shadow: 0 0 7px rgba(46, 204, 113, .7); }

/* ── GitHub gate (mandatory — no close button, no backdrop dismiss) ── */
.ps-gate {
  position: fixed; inset: 0; z-index: 90; display: none;
  align-items: center; justify-content: center; padding: 24px;
  background: rgba(4, 5, 9, .72); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
}
.ps-gate.open { display: flex; }
.ps-gate-card {
  width: min(470px, 100%); border-radius: 20px; padding: 30px 28px;
  background: var(--gal-panel); border: 1px solid var(--gal-border-2);
  box-shadow: 0 30px 90px rgba(0, 0, 0, .6);
  text-align: center;
}
.ps-gate-ic {
  width: 54px; height: 54px; margin: 0 auto 16px; border-radius: 16px;
  display: grid; place-items: center;
  background: linear-gradient(135deg, rgba(0, 212, 255, .14), rgba(124, 58, 237, .14));
  border: 1px solid rgba(0, 212, 255, .22); color: var(--gal-text);
}
.ps-gate-ic svg { width: 26px; height: 26px; }
.ps-gate-card h2 { font-family: var(--gal-head); font-weight: 700; font-size: 21px; margin: 0 0 8px; color: var(--gal-text); }
.ps-gate-card p { margin: 0 0 8px; color: var(--gal-text-dim); font-size: 14px; line-height: 1.6; }
.ps-gate-note { font-size: 12.5px; color: var(--gal-text-faint); margin: 14px 0 20px !important; }
.ps-gate-err { color: var(--gal-err); font-size: 13px; min-height: 18px; margin: 0 0 10px !important; }

.ps-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 9px;
  padding: 12px 22px; border-radius: 12px; border: 1px solid transparent; cursor: pointer;
  font-family: inherit; font-size: 14px; font-weight: 600; color: #fff;
  background: linear-gradient(135deg, var(--gal-cyan), var(--gal-violet));
  box-shadow: 0 10px 30px rgba(0, 212, 255, .22);
  transition: opacity .15s, transform .1s;
}
.ps-btn:hover { opacity: .92; }
.ps-btn:active { transform: translateY(1px); }
.ps-btn:disabled { opacity: .5; cursor: not-allowed; }
.ps-btn svg { width: 16px; height: 16px; }

/* ── Recent projects shelf ─────────────────────────────────────────
   A high-transparency glass container that sits ON the first screen —
   not something you scroll to find. Collapsed it shows one row of 3;
   "Browse all" expands it IN PLACE (no separate page) and the filters
   animate in beside the button. */
.ps-shelf {
  max-width: 1060px; width: calc(100% - 52px); margin: 0 auto 20px; padding: 16px 18px 18px;
  border-radius: 20px; flex: 0 0 auto;
  background: rgba(255, 255, 255, .035);
  border: 1px solid rgba(255, 255, 255, .09);
  -webkit-backdrop-filter: blur(26px) saturate(150%);
  backdrop-filter: blur(26px) saturate(150%);
  box-shadow: 0 18px 60px rgba(0, 0, 0, .32);
  transition: max-width .35s cubic-bezier(.4, 0, .2, 1);
}
.ps-shelf[hidden] { display: none; }
.ps-shelf-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 13px; padding: 0 4px; }
.ps-shelf-title { font-family: var(--gal-head); font-weight: 600; font-size: 15px; color: var(--gal-text); margin: 0; }
.ps-shelf-tools { display: flex; align-items: center; gap: 8px; }

/* Filters: hidden until expanded, then they slide in from the right. */
.ps-filters {
  display: flex; align-items: center; gap: 3px; padding: 3px;
  border-radius: 10px; background: rgba(255, 255, 255, .04); border: 1px solid var(--gal-border);
  opacity: 0; transform: translateX(10px); pointer-events: none;
  max-width: 0; overflow: hidden; padding-left: 0; padding-right: 0; border-color: transparent;
  transition: opacity .28s ease, transform .28s ease, max-width .34s cubic-bezier(.4, 0, .2, 1), padding .28s ease;
}
body.ps-shelf-open .ps-filters {
  opacity: 1; transform: translateX(0); pointer-events: auto;
  max-width: 340px; padding-left: 3px; padding-right: 3px; border-color: var(--gal-border);
}
.ps-filter {
  border: none; background: transparent; cursor: pointer; white-space: nowrap;
  font-family: inherit; font-size: 12px; font-weight: 500; color: var(--gal-text-dim);
  padding: 5px 10px; border-radius: 8px; transition: background .15s, color .15s;
}
.ps-filter:hover { color: var(--gal-text); }
.ps-filter.active { background: rgba(0, 212, 255, .14); color: #fff; }

.ps-browse {
  flex-shrink: 0; cursor: pointer; white-space: nowrap; font-family: inherit;
  font-size: 12px; font-weight: 600; color: var(--gal-text);
  padding: 6px 13px; border-radius: 9px;
  background: rgba(255, 255, 255, .05); border: 1px solid var(--gal-border-2);
  transition: border-color .15s, background .15s, color .15s;
}
.ps-browse:hover { border-color: var(--gal-cyan); color: var(--gal-cyan); }

/* Collapsed = exactly one row, clipped. Expanded = scrollable grid. */
/* Collapsed = exactly one row of 4 cards, shown IN FULL (was cropping the
   "Edited…" line). A card is preview(16:10) + body ≈ 250px; the extra room
   lets a card lift on hover without clipping. */
.ps-shelf-body { max-height: 270px; overflow: hidden; transition: max-height .38s cubic-bezier(.4, 0, .2, 1); }
body.ps-shelf-open .ps-shelf-body { max-height: min(60vh, 620px); overflow-y: auto; padding-right: 4px; }
.ps-rgrid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
.ps-shelf-empty { color: var(--gal-text-faint); font-size: 13px; padding: 26px 4px; text-align: center; }

.ps-rcard {
  position: relative; display: flex; flex-direction: column; text-align: left;
  padding: 0; overflow: hidden; cursor: pointer;
  border-radius: 14px; background: var(--gal-panel); border: 1px solid var(--gal-border);
  font-family: inherit; color: inherit;
  transition: border-color .15s, transform .15s, background .15s;
}
.ps-rcard:hover { border-color: var(--gal-border-2); transform: translateY(-2px); background: var(--gal-panel-2); }
/* Token-driven, never hardcoded darks: theme-light.css swaps the --gal-*
   variables and these adapt with it (per-file [data-theme] blocks lose to it). */
.ps-prev {
  position: relative; aspect-ratio: 16 / 10; overflow: hidden;
  background: var(--gal-panel-2);
  display: grid; place-items: center;
  font-family: var(--gal-head); font-weight: 800; font-size: 30px; color: var(--gal-text-faint); opacity: .85;
  border-bottom: 1px solid var(--gal-border);
}
/* The live preview: a real 1280x800 render scaled down to the card.
   JS sets the scale from the slot's measured width, so the result is
   exactly 16:10 at any card size. pointer-events:none keeps the whole
   card one click target. */
.ps-prev-frame {
  position: absolute; top: 0; left: 0;
  width: 1280px; height: 800px; border: 0;
  transform-origin: top left;
  pointer-events: none;
  opacity: 0; transition: opacity .35s ease;
  background: #fff;
}
.ps-prev-frame.in { opacity: 1; }
.ps-prev.loaded { color: transparent; }   /* hide the letter behind the render */
.ps-prev-fail { position: absolute; inset: 0; display: grid; place-items: center; font-family: var(--gal-font); font-size: 11.5px; font-weight: 500; color: var(--gal-text-faint); text-align: center; padding: 0 14px; }
.ps-rbody { padding: 9px 11px 11px; }
.ps-rname { display: flex; align-items: center; gap: 6px; font-size: 12.5px; font-weight: 600; color: var(--gal-text); }
.ps-rname span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ps-rmeta { font-size: 11px; color: var(--gal-text-faint); margin-top: 2px; }
.ps-tag { flex-shrink: 0; font-size: 9.5px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase; padding: 2px 7px; border-radius: 999px; }
.ps-tag.live { background: rgba(46, 204, 113, .15); color: var(--gal-ok); }
.ps-tag.draft { background: rgba(245, 158, 11, .15); color: #f59e0b; }

.ps-rskel { border-radius: 14px; height: 186px; border: 1px solid var(--gal-border); background: linear-gradient(90deg, var(--gal-panel) 25%, var(--gal-panel-2) 37%, var(--gal-panel) 63%); background-size: 400% 100%; animation: galSkel 1.4s ease infinite; }

/* Expanded shelf: let the grid reflow to as many columns as fit. */
body.ps-shelf-open .ps-rgrid { grid-template-columns: repeat(auto-fill, minmax(186px, 1fr)); }

/* Attachment chips above the home composer */
.ps-attach-row { display: flex; flex-wrap: wrap; gap: 6px; max-width: 760px; margin: 0 auto 8px; }
.ps-attach-row:empty { display: none; }
.ps-at {
  display: flex; align-items: center; gap: 7px; padding: 4px 8px 4px 4px; border-radius: 10px;
  background: var(--gal-panel-2); border: 1px solid var(--gal-border-2); font-size: 12px; color: var(--gal-text-dim);
}
.ps-at img { width: 26px; height: 26px; border-radius: 6px; object-fit: cover; }
.ps-at-x { cursor: pointer; color: var(--gal-text-faint); padding: 2px; }
.ps-at-x:hover { color: var(--gal-err); }

/* ── Card context menu ─────────────────────────────────────────── */
.ps-ctx {
  position: fixed; z-index: 95; min-width: 176px; display: none; padding: 5px;
  border-radius: 11px; background: var(--gal-panel); border: 1px solid var(--gal-border-2);
  box-shadow: 0 14px 44px rgba(0, 0, 0, .5);
  -webkit-backdrop-filter: blur(16px); backdrop-filter: blur(16px);
}
.ps-ctx.open { display: block; }
.ps-ctx button {
  display: flex; align-items: center; gap: 9px; width: 100%; padding: 9px 11px;
  border: none; background: none; border-radius: 8px; cursor: pointer;
  font-family: inherit; font-size: 13px; text-align: left; color: var(--gal-text);
}
.ps-ctx button:hover { background: var(--gal-panel-2); }
.ps-ctx button.danger { color: var(--gal-err); }
.ps-rmenu {
  position: absolute; top: 8px; right: 8px; z-index: 3;
  width: 26px; height: 26px; border-radius: 8px; display: grid; place-items: center;
  border: 1px solid var(--gal-border-2); background: var(--gal-panel); color: var(--gal-text-dim);
  cursor: pointer; opacity: 0; transition: opacity .15s, color .15s;
}
.ps-rcard:hover .ps-rmenu { opacity: 1; }
.ps-rmenu:hover { color: var(--gal-text); }
.ps-rmenu svg { width: 14px; height: 14px; }

/* ── Toast ─────────────────────────────────────────────────────── */
.ps-toast {
  position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%);
  z-index: 99; display: none; padding: 11px 20px; border-radius: 12px;
  background: var(--gal-panel-2); border: 1px solid var(--gal-border-2);
  font-size: 13.5px; color: var(--gal-text); box-shadow: 0 12px 40px rgba(0, 0, 0, .45);
}
.ps-toast.show { display: block; }

@media (max-width: 1080px) { .ps-rgrid { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 820px)  { .ps-rgrid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px)  { .ps-rgrid { grid-template-columns: 1fr; } }
