/* Tapp The Button - the page around the widget, and the frames it is shown in
   (Nov 2026). Loaded last.

   The standalone /tapp/ page is a page of joshtified.com, so it wears the site:
   the same night (#07060c with the violet floor-light, and on a wide screen the
   site's own sky.js over it), the same header brand markup (styled here to the
   site's measurements, never redrawn) and the site's type for the words around
   the game. The game itself keeps its own cartoon look inside its card.

   Inside a frame the page around the game is dropped and the game takes the
   frame. index.html sorts a frame into one of three sizes on every resize:
   .embed (small: the front page hero, a phone), .framed (roomy: the project
   page on a laptop) and .framed.frame-stage (a frame put into full screen, or any
   frame wider than a phone and tall enough for the whole card). */

@font-face {
  font-family: 'Bricolage';
  src: url('/assets/fonts/bricolage-latin.woff2') format('woff2');
  font-weight: 200 800;
  font-display: swap;
}

:root {
  --night: #07060c;
  --night-2: #0c0a14;
  --chalk: #f4f1f9;
  --mist: #c4bcd8;
  --dim: #8d84a6;
  --lilac: #a78bfa;
  --violet: #7c3aed;
  --violet-deep: #5b21b6;
  --site-line: rgba(244, 241, 249, .08);
  --site-line-2: rgba(244, 241, 249, .14);
  --site-display: 'Bricolage', 'Segoe UI', system-ui, sans-serif;
  --bar-h: 44px;
}

/* ------------------------------------------------------------- the night
   The old page sat on a teal field (#3f7f93) that belonged to nothing on the
   site. Now it is the site's own night: near black, a violet glow low on the
   left and a magenta one high on the right, and a few fixed stars under the
   live sky. A frame gets the same, so full screen is not a teal flash either. */
html, html body {
  background-color: var(--night) !important;
}
html { background-image: none !important; }
html body { min-height: 100%; }
html body {
  background-image:
    radial-gradient(1.2px 1.2px at 12% 18%, rgba(255, 255, 255, .7) 50%, transparent 51%),
    radial-gradient(1px 1px at 28% 72%, rgba(255, 255, 255, .5) 50%, transparent 51%),
    radial-gradient(1.4px 1.4px at 46% 12%, rgba(255, 255, 255, .6) 50%, transparent 51%),
    radial-gradient(1px 1px at 64% 86%, rgba(255, 255, 255, .45) 50%, transparent 51%),
    radial-gradient(1.2px 1.2px at 82% 30%, rgba(255, 255, 255, .6) 50%, transparent 51%),
    radial-gradient(1px 1px at 92% 64%, rgba(255, 255, 255, .5) 50%, transparent 51%),
    radial-gradient(60% 50% at 18% 100%, rgba(124, 58, 237, .30), transparent 70%),
    radial-gradient(50% 40% at 88% 0%, rgba(217, 70, 239, .14), transparent 70%),
    linear-gradient(180deg, var(--night-2) 0%, var(--night) 100%) !important;
  background-attachment: fixed;
}

/* ------------------------------------------------------- the site's bar
   The same markup as the joshtified.com header brand (the J box and the
   wordmark), at the site's sizes. On a phone it is a slim strip over the game;
   on a wide screen it is the site's 68px header. */
.site-bar {
  position: relative;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  height: var(--bar-h);
  padding: 0 14px;
  font-family: var(--site-display);
  color: var(--chalk);
  background: rgba(7, 6, 12, .86);
  border-bottom: 1px solid var(--site-line);
  user-select: auto;
}
.site-brand {
  display: flex;
  align-items: center;
  gap: 9px;
  font-family: var(--site-display);
  font-weight: 600;
  font-size: 16.5px;
  letter-spacing: -.03em;
  line-height: 1.72;
  color: var(--chalk);
  text-decoration: none;
}
.site-brand-mark {
  display: grid;
  place-items: center;
  width: 27px;
  height: 27px;
  padding-top: 1px;
  border-radius: 3px 11px 3px 3px;
  background: #141020;
  color: var(--chalk);
  font-family: var(--shout);
  font-weight: 400;
  font-size: 15px;
  box-shadow: 2px 2px 0 rgba(91, 33, 182, .3);
  transition: background .2s ease, transform .35s cubic-bezier(.16, .84, .28, 1);
}
.site-brand:hover .site-brand-mark { background: var(--violet-deep); transform: rotate(-6deg); }
.site-brand-word {
  display: block;
  padding-top: 4px;
  font-family: var(--pixel);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: .03em;
  line-height: 1;
}
.site-bar-nav { display: flex; align-items: center; gap: 2px; }
.site-bar-nav a {
  padding: 7px 10px;
  border-radius: 6px;
  font-size: 14px;
  line-height: 1.4;
  color: var(--mist);
  text-decoration: none;
  white-space: nowrap;
  transition: color .2s ease, background .2s ease;
}
.site-bar-nav a:hover { color: var(--chalk); background: rgba(124, 58, 237, .18); }
.site-bar-nav a.site-bar-home {
  margin-left: 8px;
  border: 1px solid rgba(167, 139, 250, .45);
  border-radius: 3px 12px 3px 3px;
  font-weight: 600;
  color: var(--chalk);
  background: rgba(124, 58, 237, .22);
}
.site-bar-nav a.site-bar-home:hover { background: rgba(124, 58, 237, .4); }
.site-bar-nav a:focus-visible, .site-brand:focus-visible, .intro-link:focus-visible {
  outline: 2px solid var(--lilac);
  outline-offset: 2px;
}

/* --------------------------------------------- standalone: a phone, a tablet
   The game is the page, under the slim bar. The words column stays hidden: on
   a phone the widget is the right composition, and the bar is the way back. */
html:not(.in-frame) body {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-start;
  padding: 0;
}
html:not(.in-frame):not(.embed) {
  --widget-w: 100vw;
  --widget-h: calc(100svh - var(--bar-h));
}
html:not(.in-frame) #app {
  flex: 0 0 auto;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}
html:not(.in-frame) .tapp-intro { display: none; }
@media (max-width: 640px) {
  .site-bar { padding: 0 12px; }
  .site-bar-nav a:not(.site-bar-home) { display: none; }
  .site-bar-nav a.site-bar-home { margin-left: 0; padding: 6px 10px; font-size: 13px; }
}

/* ------------------------------------------------------ standalone: wide
   A tablet held flat and up: the site's header across the top, and under it the
   words and the game side by side, the game as large as the height allows and
   drawn in its own proportions (about 2 wide to 3 tall), so it never turns into
   a stretched strip or a tiny phone card in the middle of a field. */
@media (min-width: 980px) {
  :root { --bar-h: 68px; }
  html:not(.in-frame) body {
    display: grid;
    grid-template-columns: minmax(300px, 440px) auto;
    grid-template-rows: var(--bar-h) minmax(0, 1fr);
    align-items: center;
    justify-content: center;
    column-gap: clamp(40px, 6vw, 112px);
    padding: 0 clamp(24px, 4vw, 64px);
    overflow-y: auto;
  }
  html:not(.in-frame) .site-bar {
    position: fixed;
    inset: 0 0 auto;
    height: var(--bar-h);
    padding: 0 max(32px, calc((100vw - 1280px) / 2));
    background: rgba(7, 6, 12, .72);
    backdrop-filter: blur(18px) saturate(1.3);
    -webkit-backdrop-filter: blur(18px) saturate(1.3);
  }
  .site-brand { gap: 10px; font-size: 18px; }
  .site-brand-mark { width: 30px; height: 30px; font-size: 17px; border-radius: 3px 12px 3px 3px; box-shadow: 3px 3px 0 rgba(91, 33, 182, .3); }
  .site-brand-word { font-size: 14px; }
  .site-bar-nav a { font-size: 14.5px; padding: 8px 12px; }

  html:not(.in-frame):not(.embed) {
    --widget-h: min(960px, calc(100svh - var(--bar-h) - 40px));
    --widget-w: min(660px, calc(var(--widget-h) * .68));
  }
  html:not(.in-frame) #app {
    grid-column: 2;
    grid-row: 2;
    z-index: 45;
    border: 3px solid #2c2416;
    border-radius: 26px;
    box-shadow: 0 0 0 1px rgba(167, 139, 250, .25), 0 40px 90px -30px rgba(124, 58, 237, .55), 0 24px 60px rgba(0, 0, 0, .55);
  }
  html:not(.in-frame) .tapp-intro {
    grid-column: 1;
    grid-row: 2;
    position: relative;
    z-index: 1;
    display: block;
    max-width: 440px;
    max-height: calc(100svh - var(--bar-h) - 24px);
    overflow-y: auto;
    scrollbar-width: thin;
    padding: 12px 6px 12px 0;
    font-family: var(--site-display);
    color: var(--chalk);
    text-shadow: none;
    user-select: text;
  }
  /* Crisp, in the site's ink. The old title was a pale gradient clipped to the
     letters with a text shadow showing through them, which is what read as
     faded: a solid colour, no shadow, and the second line in the site's lilac. */
  html:not(.in-frame) .tapp-intro .intro-title {
    margin: 0 0 16px;
    font-family: var(--shout);
    font-weight: 400;
    font-size: clamp(2.4rem, min(4vw, 6.4vh), 3.8rem);
    line-height: .98;
    letter-spacing: 0;
    color: var(--chalk);
    background: none;
    -webkit-background-clip: border-box;
    background-clip: border-box;
    filter: none;
    text-shadow: none;
  }
  html:not(.in-frame) .tapp-intro .intro-title span { display: block; color: var(--lilac); }
  html:not(.in-frame) .tapp-intro .intro-kicker {
    margin: 0 0 14px;
    font-family: var(--pixel);
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--lilac);
    text-shadow: none;
  }
  html:not(.in-frame) .tapp-intro .intro-lede {
    margin: 0 0 clamp(16px, 3vh, 26px);
    font-size: clamp(15px, 2vh, 17px);
    line-height: 1.55;
    color: var(--mist);
  }
  html:not(.in-frame) .tapp-intro .intro-points { display: grid; gap: clamp(8px, 1.6vh, 14px); margin: 0; padding: 0; list-style: none; }
  html:not(.in-frame) .tapp-intro .intro-points li { padding-left: 14px; border-left: 2px solid rgba(167, 139, 250, .45); }
  html:not(.in-frame) .tapp-intro .intro-points b {
    display: block;
    font-family: var(--site-display);
    font-size: 15px;
    font-weight: 650;
    letter-spacing: 0;
    text-transform: none;
    color: var(--chalk);
  }
  html:not(.in-frame) .tapp-intro .intro-points span {
    display: block;
    margin-top: 2px;
    font-size: clamp(13px, 1.65vh, 14.5px);
    line-height: 1.5;
    color: var(--dim);
  }
  html:not(.in-frame) .tapp-intro .intro-links { display: flex; flex-wrap: wrap; gap: 10px; margin: clamp(16px, 3vh, 28px) 0 0; }
  .intro-link {
    display: inline-flex;
    align-items: center;
    padding: 9px 14px;
    border: 1px solid var(--site-line-2);
    border-radius: 3px 12px 3px 3px;
    font-size: 14.5px;
    font-weight: 600;
    color: var(--chalk);
    text-decoration: none;
    transition: background .2s ease, border-color .2s ease;
  }
  .intro-link:hover { background: rgba(124, 58, 237, .2); border-color: rgba(167, 139, 250, .5); }
  .intro-link--main { border-color: transparent; background: linear-gradient(100deg, #7c3aed, #a855f7); box-shadow: 0 10px 30px -12px rgba(124, 58, 237, .8); }
  .intro-link--main:hover { background: linear-gradient(100deg, #6d28d9, #9333ea); }
}
/* A short laptop screen (720px) has room for the title and the five points
   only if the descriptions go one size down and the lede tightens; anything
   still taller than the screen scrolls inside the column, never the game. */
@media (min-width: 980px) and (max-height: 820px) {
  html:not(.in-frame) .tapp-intro .intro-title { font-size: clamp(2.2rem, 6.4vh, 3rem); margin-bottom: 10px; }
  html:not(.in-frame) .tapp-intro .intro-kicker { margin-bottom: 10px; }
  html:not(.in-frame) .tapp-intro .intro-lede { font-size: 14px; line-height: 1.5; }
  html:not(.in-frame) .tapp-intro .intro-points span { font-size: 12.5px; line-height: 1.42; }
  html:not(.in-frame) .tapp-intro .intro-points b { font-size: 14px; }
}

/* ---------------------------------------------------------------- in a frame */
html.in-frame .site-bar,
html.in-frame .tapp-intro { display: none !important; }
html.in-frame body { display: flex; align-items: center; justify-content: center; padding: 0; }
/* roomy frame: the game is the frame, edge to edge */
html.in-frame.framed { --widget-w: 100vw; --widget-h: 100vh; }
html.in-frame.framed #app,
html.in-frame.embed #app { border: 0; border-radius: 0; box-shadow: none; }
/* full screen (or any frame that is wider than the game wants): the card in its
   own proportions, as large as the height allows, centred on the site's night */
html.in-frame.framed.frame-stage {
  --widget-h: min(1000px, calc(100vh - 40px));
  --widget-w: min(700px, calc(var(--widget-h) * .68), calc(100vw - 32px));
}
html.in-frame.framed.frame-stage #app {
  border: 3px solid #2c2416;
  border-radius: 26px;
  box-shadow: 0 0 0 1px rgba(167, 139, 250, .25), 0 40px 90px -30px rgba(124, 58, 237, .55), 0 24px 60px rgba(0, 0, 0, .55);
}

/* ------------------------------------------------------------ the panels
   Six shelf tabs in one scrolling row hid Reboot (and on the front page Scenes)
   off the edge of a narrow sheet with no sign that it was there. Under 560px
   the row wraps, so every shelf is always on screen. */
@media (max-width: 560px) {
  #app .shop-tabs { flex-wrap: wrap !important; overflow: visible !important; row-gap: 6px !important; }
}
/* In a small frame the sheet gets nearly all of the height, and its head and
   tabs are tighter, so the shelf itself is not a slot two rows high. */
html.embed #app .panel { max-height: calc(100% - 10px) !important; padding: 6px 12px calc(12px + var(--safe-bottom)) !important; border-radius: 20px 20px 0 0 !important; }
html.embed #app .panel::before { margin-bottom: 4px !important; }
html.embed #app .panel-head { margin: 0 -12px 6px !important; padding: 2px 12px 6px !important; }
html.embed #app .panel-head h2 { font-size: 1.15rem !important; }
html.embed #app .close-btn { width: 30px !important; height: 30px !important; }
html.embed #app .shop-tabs { margin: 0 -12px 8px !important; padding: 2px 12px 4px !important; gap: 5px !important; }
html.embed #app .shop-tab { padding: 6px 11px !important; font-size: .76rem !important; }
/* A sheet on a wide card or a full screen is a sheet, not a full-width slab. */
html:not(.embed) #app .panel { max-width: min(620px, 100%) !important; }

/* A card close to 1000px tall (a 1080p screen, or full screen) held the HUD at
   its 16px reading size, so the chips, the ad and the plates looked small and
   lost in a big field. Past 940px of height the root steps up to 18px; every rem
   in the widget grows with it and the 660px card still has the width for it. */
@media (min-width: 980px) and (min-height: 1040px) {
  html:not(.in-frame):not(.embed) { font-size: 18px; }
}
@media (min-height: 1000px) and (min-width: 900px) {
  html.in-frame.framed.frame-stage { font-size: 18px; }
}
