/* ==========================================================================
Pikback — global styles (1): shell, top/bottom nav, swipe browsing
   Design intent: dark theme, portrait-first, one-thumb use, transform/opacity-only animation.
   ========================================================================== */

@import url('studio.css');

:root {
  --bg: #0b0c13;
  --bg-2: #12141f;
  --card: #191c29;
  --line: rgba(255, 255, 255, .10);
  --text: #f2f4f8;
  --muted: rgba(242, 244, 248, .58);
  --accent: #ffb01f;
  --accent-2: #ffd76e;
  --danger: #ff6b6b;
  --header-h: 52px;

  --radius: 16px;
}

* {
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
}

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Microsoft YaHei", "Segoe UI", sans-serif;
  -webkit-font-smoothing: antialiased;
  overscroll-behavior: none;
}

body { position: fixed; inset: 0; }

button { font-family: inherit; cursor: pointer; }
input, textarea { font-family: inherit; }

#app {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
}

/* ------------------------------ top nav ------------------------------- */

.app-header {
  position: relative;
  z-index: 30;
  flex: 0 0 auto;
  height: calc(var(--header-h) + env(safe-area-inset-top));
  padding: env(safe-area-inset-top) 14px 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: linear-gradient(180deg, rgba(11, 12, 19, .96), rgba(11, 12, 19, .72));
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--line);
}

.brand { display: flex; align-items: center; gap: 8px; min-width: 0; }
.brand .logo {
  width: 28px; height: 28px; flex: 0 0 auto;
  display: flex; align-items: center; justify-content: center;
  font-size: 18px; line-height: 1;
  border-radius: 8px;
  overflow: hidden;
  background: rgba(255, 255, 255, .08);
  border: 1px solid var(--line);
}
.brand .logo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.brand .name {
  font-size: 16px; font-weight: 700; letter-spacing: .2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 52vw;
}
.header-actions { display: flex; gap: 6px; }
.icon-btn {
  width: 38px; height: 38px; border-radius: 50%;
  border: 1px solid var(--line); background: rgba(255, 255, 255, .05);
  color: var(--text); font-size: 16px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
  transition: transform .14s ease, background .14s;
}
.icon-btn:active { transform: scale(.9); background: rgba(255, 255, 255, .12); }

/*
 * A class the code can toggle to take a header control out of the layout.
 *
 * display:none rather than visibility or opacity: a hidden control should not
 * keep its space, or the row would leave a gap where the button used to be.
 * !important is deliberate — this has to win over the control's own display
 * rules (.icon-btn sets display:flex).
 */
.header-actions .hidden { display: none !important; }

/* ------------------------------ main area ----------------------------- */

.app-main { position: relative; flex: 1 1 auto; min-height: 0; overflow: hidden; }
.app-main.scrollable { overflow-y: auto; -webkit-overflow-scrolling: touch; background: var(--bg-2); }

/* ---------------------------- mode switch ----------------------------- */

/*
 * Play / Create, as a two-position switch in the header.
 *
 * Sized to the icon buttons beside it so the row stays even, and slightly wider
 * because it holds two glyphs rather than one. The knob slides rather than the
 * glyphs changing, which is what makes it read as a position the user can be in
 * rather than an action they take.
 */
.mode-switch {
  position: relative;
  width: 72px; height: 38px; flex: 0 0 auto;
  padding: 0; border-radius: 999px;
  border: 1px solid var(--line);
  background: rgba(255, 255, 255, .05);
  display: flex; align-items: center;
  cursor: pointer;
  transition: border-color .16s ease;
}
.mode-switch .mode-opt {
  position: relative; z-index: 1;
  flex: 1 1 0; display: grid; place-items: center;
  font-size: 15px; line-height: 1;
  opacity: .45; transition: opacity .18s ease;
}
/* The selected glyph is fully lit; the other stays dim so the current mode is
   readable at a glance without a label. */
.mode-switch .mode-opt[data-mode="play"] { opacity: 1; }
.mode-switch.on .mode-opt[data-mode="play"] { opacity: .45; }
.mode-switch.on .mode-opt[data-mode="make"] { opacity: 1; }
.mode-switch .mode-knob {
  position: absolute; top: 3px; left: 3px;
  width: 32px; height: 32px; border-radius: 999px;
  background: linear-gradient(135deg, var(--accent-2), var(--accent));
  transition: transform .2s cubic-bezier(.34, 1.56, .64, 1);
  pointer-events: none;
}
.mode-switch.on .mode-knob { transform: translateX(34px); }
.mode-switch:active { transform: scale(.95); }

/* ================================= Play ================================ */

.feed { position: absolute; inset: 0; overflow: hidden; touch-action: none; }
.feed-rail { position: absolute; inset: 0; }

.feed-card {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background: #05060a;
  will-change: transform;
  transition: transform .26s cubic-bezier(.22, .61, .36, 1);
}
.feed.dragging .feed-card { transition: none; }
.feed.snapping .feed-card { transition: transform .26s cubic-bezier(.22, .61, .36, 1); }

.card-cover {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover;
  filter: saturate(1.05);
}

/* Title card -----------------------------------------------------------------
   Shown while a game loads and whenever the card is not the active one.
   It introduces the game as an icon + name, and doubles as the loading state
   (the cover is already cached from the card behind it, so there is no flash).
   -------------------------------------------------------------------------- */
.card-veil {
  position: absolute; inset: 0;
  z-index: 2;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 14px;
  padding: 40px 28px calc(80px + env(safe-area-inset-bottom));
  text-align: center;
  background: radial-gradient(120% 70% at 50% 34%, rgba(0, 0, 0, .42), rgba(0, 0, 0, .88));
  backdrop-filter: blur(2px);
  transition: opacity .32s ease, transform .32s ease;
}
.feed-card.is-active .card-veil { opacity: 0; pointer-events: none; transform: scale(1.03); }

/* The cover doubles as the app icon: rounded, ringed, and lifted off the photo. */
.veil-icon {
  width: 108px; height: 108px; flex: 0 0 auto;
  border-radius: 26px;
  overflow: hidden;
  background: rgba(255, 255, 255, .08);
  border: 1px solid rgba(255, 255, 255, .22);
  box-shadow: 0 16px 40px rgba(0, 0, 0, .55), 0 0 0 6px rgba(255, 255, 255, .06);
}
.veil-icon img { width: 100%; height: 100%; object-fit: cover; display: block; }

.veil-title {
  margin: 0;
  font-size: 25px; font-weight: 800; line-height: 1.28;
  text-shadow: 0 2px 18px rgba(0, 0, 0, .7);
  max-width: 280px;
}
.veil-sub {
  font-size: 13px; padding: 6px 14px; border-radius: 999px;
  background: var(--accent); color: #17181f; font-weight: 700;
}
.veil-hint {
  margin-top: 6px;
  font-size: 11.5px; color: rgba(255, 255, 255, .62);
  max-width: 250px; line-height: 1.5;
}

.game-frame {
  position: absolute; inset: 0;
  width: 100%; height: 100%; border: 0; background: #0b0c13;
}

/* Drawer actions -----------------------------------------------------------
   Only a slim handle sits on the right edge; tapping it slides the buttons out.
   Collapsed, only a 26px handle remains, so gameplay is never covered.
   ---------------------------------------------------------------------- */
.card-side {
  position: absolute;
  right: 0;
  bottom: calc(150px + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 12px;
  z-index: 7;
  padding: 8px 0;
  /* Collapsed: push the button column off-screen, leaving only the handle.
     Offset must be >= button width (50) + right gap (34), or a sliver of button shows. */
  transform: translateX(var(--side-hide, 86px));
  transition: transform .26s cubic-bezier(.22, .61, .36, 1);
}
.card-side.open { transform: translateX(0); }

/* Edge handle: always visible; this is the drawer toggle.
   It is a direct child of .feed-card, so it does not move with the drawer. */
.side-tab {
  position: absolute;
  right: 0;
  bottom: calc(210px + env(safe-area-inset-bottom));
  width: 26px;
  height: 62px;
  z-index: 8;
  border: 0;
  border-radius: 10px 0 0 10px;
  background: rgba(0, 0, 0, .42);
  border-left: 1px solid rgba(255, 255, 255, .18);
  border-top: 1px solid rgba(255, 255, 255, .18);
  border-bottom: 1px solid rgba(255, 255, 255, .18);
  color: #fff;
  font-size: 15px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  backdrop-filter: blur(8px);
  cursor: pointer;
  transition: background .18s ease;
}
.side-tab:active { background: rgba(255, 255, 255, .22); }
.side-tab .tab-chev {
  display: block;
  transition: transform .26s cubic-bezier(.22, .61, .36, 1);
}
.card-side.open .side-tab .tab-chev { transform: rotate(180deg); }

/* Gap between the button column and the handle when open */
.card-side > .side-btn { margin-right: 34px; }
.card-side > .side-btn:first-of-type { margin-top: 6px; }
.card-side > .side-btn:last-of-type { margin-bottom: 6px; }
.side-btn {
  width: 50px; border: 0; background: transparent; color: #fff;
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  font-size: 10px; font-weight: 600; text-shadow: 0 1px 8px rgba(0, 0, 0, .7);
}
.side-btn .i {
  width: 46px; height: 46px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; font-size: 21px;
  background: rgba(255, 255, 255, .14);
  border: 1px solid rgba(255, 255, 255, .18);
  backdrop-filter: blur(8px);
  transition: transform .18s cubic-bezier(.34, 1.56, .64, 1), background .18s;
}
.side-btn:active .i { transform: scale(.88); }
.side-btn.on .i { background: rgba(255, 176, 31, .9); border-color: transparent; }
.side-btn.on { color: var(--accent-2); }
.side-btn.pulse .i { animation: pop .42s cubic-bezier(.34, 1.56, .64, 1); }
@keyframes pop {
  0% { transform: scale(1); }
  45% { transform: scale(1.32); }
  100% { transform: scale(1); }
}

/* Top / bottom swipe bars --------------------------------------------------
   The card hosts a game; the iframe swallows pointer events, so the parent
   never sees the drag. The swipe gesture therefore lives on two thin bars at the
   top and bottom of the screen, layered above the iframe, leaving the middle free.
   Direction matches position: swipe up on the bottom bar for the next game, down on the top bar for the previous.
   ---------------------------------------------------------------------- */
.card-edge {
  position: absolute;
  left: 0;
  right: 0;
  height: 46px;
  z-index: 6;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  touch-action: none;
  -webkit-user-select: none;
  user-select: none;
  cursor: grab;
  background: transparent;
  transition: background .2s ease;
}
.card-edge-up { bottom: 0; padding-bottom: env(safe-area-inset-bottom); }
.card-edge-down { top: 0; padding-top: env(safe-area-inset-top); }
.card-edge:active { cursor: grabbing; background: rgba(255, 255, 255, .10); }

/* Inactive cards (cover preview only) need no gesture area */
.feed-card:not(.is-active) .card-edge { pointer-events: none; }

/* A small grip and hint label make the bars discoverable */
.card-edge .bar-grip {
  width: 46px;
  height: 4px;
  border-radius: 999px;
  background: rgba(255, 255, 255, .8);
  box-shadow: 0 1px 6px rgba(0, 0, 0, .55);
}
.card-edge .bar-hint {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: .3px;
  color: rgba(255, 255, 255, .92);
  text-shadow: 0 1px 6px rgba(0, 0, 0, .85);
}

/* On the active card, a gradient blends each bar into the artwork */
.feed-card.is-active .card-edge-up {
  background: linear-gradient(0deg, rgba(0, 0, 0, .5), rgba(0, 0, 0, 0));
}
.feed-card.is-active .card-edge-down {
  background: linear-gradient(180deg, rgba(0, 0, 0, .5), rgba(0, 0, 0, 0));
}
.card-edge-up .bar-grip { animation: nudge-up 1.8s ease-in-out infinite; }
.card-edge-down .bar-grip { animation: nudge-down 1.8s ease-in-out infinite; }
@keyframes nudge-up {
  0%, 100% { transform: translateY(1px); opacity: .6; }
  50% { transform: translateY(-3px); opacity: 1; }
}
@keyframes nudge-down {
  0%, 100% { transform: translateY(-1px); opacity: .6; }
  50% { transform: translateY(3px); opacity: 1; }
}

/* ============================== shared UI ============================== */

.muted { color: var(--muted); font-size: 12px; }
.muted.center { text-align: center; }

.row { display: flex; align-items: center; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
.actions { display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap; }

.primary, .ghost {
  border-radius: 999px; padding: 11px 20px; font-size: 14px; font-weight: 700;
  border: 1px solid transparent; transition: transform .14s ease, background .16s, opacity .16s;
}
.primary { background: linear-gradient(135deg, var(--accent-2), var(--accent)); color: #17181f; }
.ghost { background: rgba(255, 255, 255, .07); border-color: var(--line); color: var(--text); }
.ghost.mini { padding: 7px 13px; font-size: 12px; }
.ghost.danger, .danger { color: var(--danger); border-color: rgba(255, 107, 107, .35); }
.primary:active, .ghost:active { transform: scale(.96); }
.primary:disabled, .ghost:disabled { opacity: .5; }

/* ================================ toast ================================ */

.toast {
  position: fixed; left: 50%; bottom: calc(env(safe-area-inset-bottom) + 26px);
  transform: translate(-50%, 12px);
  max-width: 84vw; padding: 11px 18px; border-radius: 999px;
  background: rgba(20, 22, 32, .96); border: 1px solid var(--line); color: var(--text);
  font-size: 13px; line-height: 1.45; text-align: center;
  opacity: 0; pointer-events: none; z-index: 90;
  transition: opacity .22s ease, transform .22s cubic-bezier(.34, 1.56, .64, 1);
  box-shadow: 0 12px 30px rgba(0, 0, 0, .45);
}
.toast.show { opacity: 1; transform: translate(-50%, 0); }

/* ============================= responsive ============================== */

@media (min-width: 700px) {
  .feed-card { max-width: 430px; left: 50%; margin-left: -215px; }
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
