/* Type: Inter for everything you read and press, and PP Playground Medium (the face in the logo) for page titles.
   Both are served from the site (assets/fonts; see FONTS.txt for their licences). */
@font-face { font-family: Inter; font-style: normal; font-weight: 400 600; font-display: swap; src: url(/assets/fonts/inter-latin.woff2) format("woff2"); }
@font-face { font-family: "PP Playground"; font-style: normal; font-weight: 500; font-display: swap; src: url(/assets/fonts/pp-playground-medium-latin.woff2) format("woff2"); }
:root {
  --bg: #08090b;
  --text: #8f9298;
  --strong: #e6e7ea;
  --faint: #5d6066;
  --surface: #141518;
  --title: "PP Playground", Inter, ui-sans-serif, system-ui, sans-serif;
  --heat-glow: radial-gradient(70% 120% at 50% 55%, #ffe6794d, #ff991e42 30%, #ff298d29 60%, #9e5af200 85%);
  --surface-2: #1d1f23;
  --line: #ffffff0f;
  --gutter: clamp(20px, 5vw, 64px);
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --lamp: #f3d59e;   /* the one warm colour: a desk light left on, meaning "this one is open" */
  /* For Home's box and the Dumbo map (Sai's design pass), in the house's dark colours. */
  --ink: #e6e7ea;            /* the box's lines */
  --map-paper: #08090b;      /* the Dumbo map's paper: the map's land (src/plan.js) */
  --rule-soft: #ffffff1a;
  --rule-strong: #ffffff4d;
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
  color-scheme: dark;
  background: var(--bg);
}
* { box-sizing: border-box; }
body {
  margin: 0;
  min-height: 100svh;
  background: var(--bg);
  color: var(--text);
  font: 400 16px/1.6 Inter, ui-sans-serif, system-ui, -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
}
a { color: inherit; text-decoration: none; }
button { font: inherit; }

/* Moving between pages (Sai's router.js): the header stays put and the rest crossfades; between Home and Join or Host
   the box's edges morph into the room's outline. */
@view-transition { navigation: auto; }
::view-transition-old(root) { animation: 260ms var(--ease-out) both page-out; }
::view-transition-new(root) { animation: 420ms var(--ease-out) 260ms both page-in; }
@keyframes page-out { to { opacity: 0; } }
@keyframes page-in { from { opacity: 0; } }
.morph { position: fixed; z-index: 9; inset: 0; inline-size: 100%; block-size: 100%; pointer-events: none; }
.morph line { stroke: var(--ink); stroke-width: 1.5px; stroke-linecap: round; }
@media (prefers-reduced-motion: reduce) { ::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; } }

/* Header: the logo on the left, the pages in the middle, the two actions on the right. On phones the pages fold
   into a menu (the nav is a popover there, opened by the menu button, so it works without scripts). */
.topbar {
  position: fixed; z-index: 10; inset: 0 0 auto;
  display: grid; grid-template-columns: 1fr auto 1fr; grid-template-areas: "brand nav actions"; align-items: center; gap: 12px 24px;
  padding: max(18px, env(safe-area-inset-top)) var(--gutter) 0;
  view-transition-name: topbar;
}
.brand { grid-area: brand; justify-self: start; position: relative; display: block; inline-size: 132px; block-size: 39px; border-radius: 6px; transform: translateY(-18.3%); }
/* The heat logo: a still of its first moment (so it shows at once, even without scripts), then the live one
   (src/heat.js via brand.js) drawn over it. The link is the size of the letters; the picture spills past them by the
   lockup's empty margin so the glow is never cut off. HOUSE's letters sit at 68.3% of the link's height (the raised
   "nd" takes the top), so the link moves up 18.3% to put HOUSE, not the whole lockup, on the header's centre line,
   level with the nav and the buttons. */
.brand-heat { position: absolute; inset-inline-start: -18.5%; inset-block-start: -62.35%; inline-size: 136.82%; block-size: 224.7%; max-inline-size: none; pointer-events: none; }
.is-live > .brand-still { visibility: hidden; }
.brand:focus-visible { outline: 2px solid var(--faint); outline-offset: 6px; }
/* Home: while the back wall (with the big logo and its own Join and Host) faces you, the header's logo and buttons
   step aside; they come back once the box turns (box.js sets .wall-facing). Home's HTML starts with the class, so they
   aren't shown and then faded on load. The phone's menu button stays, but waits until box.js has set where it sits. */
.wall-facing .topbar .brand, .wall-facing .topbar-actions > .button { opacity: 0; pointer-events: none; }
/* Every page: the same once the footer's big logo is in view (brand.js sets .footer-logo-shown). */
.footer-logo-shown .topbar .brand { opacity: 0; pointer-events: none; }
@media (scripting: enabled) { .home-page .topbar:not([data-edges]) .topbar-actions { opacity: 0; } }
/* Home: the logo and buttons slide in off the box's edges (box.js sets how far), and slide back out to the margins on
   other pages. Between pages the view transition carries them (their own names, so they move instead of crossfading
   inside the header's snapshot); the CSS transition covers the morph to Join and Host, which doesn't use one. */
.topbar .brand { translate: var(--edge-l, 0px) 0; view-transition-name: brand; }
.topbar-actions { translate: calc(-1 * var(--edge-r, 0px)) 0; view-transition-name: actions; }
.brand, .topbar-actions { transition: opacity 400ms var(--ease-out), translate 480ms var(--ease-out); }
:root:active-view-transition :is(.brand, .topbar-actions) { transition: opacity 400ms var(--ease-out); }
::view-transition-group(brand), ::view-transition-group(actions) { animation-duration: 480ms; animation-timing-function: var(--ease-out); }
.nav { grid-area: nav; display: flex; gap: 28px; font-size: 14px; }
/* Undo the popover's own box on wide screens, where the nav is just a row of links. */
.nav[popover] { position: static; inset: auto; inline-size: auto; block-size: auto; margin: 0; padding: 0; border: 0; background: none; color: inherit; overflow: visible; }
.nav-more, .menu-toggle { display: none; }
.nav-link { padding: 6px 0; color: var(--strong); opacity: .48; transition: opacity 200ms var(--ease-out); }
.nav-link[aria-current="page"] { opacity: 1; }
/* The page you're on: its name in the logo's heat (wide screens; the phone menu keeps its own look). */
@media (min-width: 761px) { .nav-link[aria-current="page"] { background: linear-gradient(90deg, #ff298d, #ff991e 55%, #ffe679); -webkit-background-clip: text; background-clip: text; color: transparent; } }
.nav-q { margin-inline-start: 3px; font-size: .9em; }
.nav-link:focus-visible { opacity: 1; outline: 2px solid var(--faint); outline-offset: 4px; border-radius: 6px; }
@media (hover: hover) and (pointer: fine) { .nav-link:hover { opacity: 1; } }
.topbar-actions { grid-area: actions; justify-self: end; display: flex; align-items: center; gap: 8px; }
.topbar .button { gap: 0; height: 36px; min-inline-size: 76px; padding-inline: 16px; font-size: 14px; }
.visually-hidden { position: absolute; inline-size: 1px; block-size: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
/* Long pages scroll under the header, so the top of the window fades to the background behind it. */
body::before {
  content: ""; position: fixed; z-index: 9; inset: 0 0 auto; block-size: calc(96px + env(safe-area-inset-top)); pointer-events: none;
  background: linear-gradient(to bottom, var(--bg) 60%, #08090b00);
}
/* Phones: logo and actions on one row, the pages on a second row below. */
@media (max-width: 760px) {
  .topbar { grid-template-columns: auto 1fr; grid-template-areas: "brand actions" "nav nav"; padding-block-start: max(14px, env(safe-area-inset-top)); }
  .brand { inline-size: 108px; block-size: 32px; }
  .nav { justify-self: center; gap: 16px; font-size: 13px; }
  .topbar .button { height: 32px; padding-inline: 13px; font-size: 13px; }
  .wide-only { display: none; }
  body::before { block-size: calc(124px + env(safe-area-inset-top)); }
}
/* Phones, where the browser has popovers (nearly all now): one row of logo, Join and a menu button. The menu opens
   under that row and fills the screen: the pages large, then Host an event and Join at the foot. Without popovers
   the second row of links above stays. */
@supports selector(:popover-open) {
  @media (max-width: 760px) {
    .topbar { grid-template-areas: "brand actions"; padding-block-end: 10px; }
    .topbar-actions > .button-quiet { display: none; }
    .menu-toggle {
      display: grid; place-items: center; inline-size: 32px; block-size: 32px; padding: 0; border: 0; border-radius: 6px;
      background: transparent; box-shadow: inset 0 0 0 1px #ffffff33; color: var(--strong); cursor: pointer;
      transition: transform 160ms var(--ease-out), background-color 200ms var(--ease-out);
    }
    .menu-toggle:active { transform: scale(.94); }
    .menu-toggle:focus-visible { outline: 2px solid var(--text); outline-offset: 3px; }
    .menu-toggle svg { inline-size: 18px; block-size: 18px; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; }
    .menu-toggle .menu-close, .topbar:has(.nav:popover-open) .menu-open { display: none; }
    .topbar:has(.nav:popover-open) .menu-close { display: inline; }
    .topbar:has(.nav:popover-open) .menu-toggle { background: #ffffff14; }
    /* Open, the header's row is part of the sheet: solid behind it (so nothing of the page, like Home's box, shows
       above the links), with the logo there even where the page had it step aside. */
    .topbar:has(.nav:popover-open) { background: var(--bg); }
    .topbar:has(.nav:popover-open) .brand { opacity: 1; pointer-events: auto; }

    .nav[popover] {
      position: fixed; inset: calc(max(14px, env(safe-area-inset-top)) + 42px) 0 0; inline-size: auto; block-size: auto; margin: 0;
      justify-self: stretch; align-self: stretch;   /* (the row of links above is centred; the sheet fills the screen) */
      display: flex; flex-direction: column; gap: 0; padding: 8px var(--gutter) max(24px, env(safe-area-inset-bottom));
      background: var(--bg); color: var(--strong); overflow-y: auto; overscroll-behavior: contain; font-size: 15px;
      transition: opacity 220ms var(--ease-out), translate 220ms var(--ease-out), overlay 220ms allow-discrete, display 220ms allow-discrete;
    }
    .nav[popover]:not(:popover-open) { display: none; opacity: 0; translate: 0 -8px; }
    @starting-style { .nav[popover]:popover-open { opacity: 0; translate: 0 -8px; } }
    .nav[popover]::backdrop { background: transparent; }
    .nav .nav-link { padding: 14px 0; border-block-end: 1px solid var(--line); font-size: 28px; line-height: 1.15; letter-spacing: -.01em; opacity: .5; }
    .nav .nav-link[aria-current="page"] { opacity: 1; }
    .nav-more { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin-block-start: auto; padding-block-start: 28px; }
    .topbar .nav-more .button { height: 48px; padding-inline: 16px; font-size: 15px; }
    html:has(.nav:popover-open) { overflow: hidden; }
    body::before { block-size: calc(84px + env(safe-area-inset-top)); }
  }
}

.page { width: min(100% - 2 * var(--gutter), 38rem); margin: 0 auto; padding: 136px 0 18vh; }
.page h1 { margin: 0 0 1.25rem; font-size: inherit; font-weight: 500; color: var(--strong); }
/* Page titles: the italic serif, large enough to lead the page. */
.page-title, .page > h1, .mark-head > h1 { font-family: var(--title); font-weight: 500; font-size: clamp(34px, 3.4vw, 44px); line-height: 1.05; letter-spacing: -.01em; color: var(--strong); }
/* Every page title lights up like the logo under a mouse pointer: src/title-heat.js draws the title's own words as
   heat in a canvas laid right over them (.title-heat-canvas), and the plain letters fade out underneath. */
:is(.page-title, .page > h1, .mark-head > h1, .events-head h1, .list-head h1, .ads-head h1, .host-head h1) { inline-size: fit-content; }
.title-heat { position: relative; transition: color 450ms var(--ease-out); }
.title-heat.is-hot { color: transparent; }
.title-heat-canvas { position: absolute; max-inline-size: none; pointer-events: none; opacity: 0; transition: opacity 450ms var(--ease-out); }
.title-heat.is-hot .title-heat-canvas { opacity: 1; }
@media (prefers-reduced-motion: reduce) { .title-heat, .title-heat-canvas { transition: none; } }
.page p { margin: 0 0 1rem; }

/* The main action on a page: the same white pill as the shop's Buy button, a size up. */
.button {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px; height: 46px; padding-inline: 24px;
  border: 0; border-radius: 6px; background: var(--strong); color: var(--bg); font-size: 15px; font-weight: 500; cursor: pointer;
  transition: transform 160ms var(--ease-out), opacity 200ms var(--ease-out);
}
.button:active { transform: scale(0.97); }
.button:focus-visible { outline: 2px solid var(--text); outline-offset: 3px; }
.button[aria-busy="true"] { opacity: .6; cursor: progress; }
/* A little warmth under a button you point at. */
@media (hover: hover) and (pointer: fine) { .button:hover { opacity: 1; box-shadow: 0 6px 22px -8px #ff6a1fa6; } .button-quiet:hover { box-shadow: inset 0 0 0 1px #ffffff59, 0 6px 22px -10px #ff6a1f8c; } }
/* The second action next to a main one: same pill, outlined. */
.button-quiet { background: transparent; color: var(--strong); box-shadow: inset 0 0 0 1px #ffffff40; }
@media (hover: hover) and (pointer: fine) { .button-quiet:hover { opacity: 1; background: #ffffff0f; } }
.text-link { color: var(--strong); text-decoration: underline; text-decoration-color: #ffffff38; text-underline-offset: 4px; transition: text-decoration-color 200ms var(--ease-out); }
.text-link:focus-visible { outline: 2px solid var(--faint); outline-offset: 4px; border-radius: 4px; }
@media (hover: hover) and (pointer: fine) { .text-link:hover { text-decoration-color: var(--strong); } }
@media (prefers-reduced-motion: reduce) { .button { transition: opacity 200ms var(--ease-out); } .button:active { transform: none; } }

/* Footer: the logo and a line about the place, then where to find us and the ways in. */
.footer {
  inline-size: min(100% - 2 * var(--gutter), 84rem); margin: 0 auto; padding: 56px 0 max(32px, env(safe-area-inset-bottom));
  border-block-start: 1px solid var(--line); font-size: 14px;
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr); gap: 40px clamp(32px, 6vw, 96px);
}
.footer-intro { display: grid; justify-items: start; align-content: start; gap: 16px; }
.footer-intro p { margin: 0; max-inline-size: 22rem; color: var(--text); text-wrap: pretty; }
.footer-brand { position: relative; display: block; inline-size: 228px; block-size: 68px; margin-block-end: 8px; border-radius: 6px; }
.footer-brand:focus-visible { outline: 2px solid var(--faint); outline-offset: 6px; }
.footer .button { height: 36px; padding-inline: 16px; font-size: 14px; }
.footer-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.footer-cols { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 32px; }
.footer-col { display: grid; align-content: start; justify-items: start; gap: 8px; }
.footer-col h2 { margin: 0 0 6px; font-size: 13px; font-weight: 500; color: var(--faint); }
.footer-col p { margin: 0; color: var(--text); }
.footer-col a { color: var(--text); transition: color 200ms var(--ease-out); }
.footer-col a:focus-visible { outline: 2px solid var(--faint); outline-offset: 4px; border-radius: 4px; }
@media (hover: hover) and (pointer: fine) { .footer-col a:hover { color: var(--strong); } }
.footer-train { display: flex; align-items: center; gap: 8px; }
.footer-train .line { display: inline-grid; place-items: center; inline-size: 18px; block-size: 18px; border-radius: 50%; background: #ff6319; color: #fff; font-size: 10px; font-weight: 700; }
.footer-fine { grid-column: 1 / -1; margin: 8px 0 0; font-size: 13px; color: var(--faint); }
/* The floor plan along the bottom (src/floor.js): the room from above, people walking about it as heat. */
.footer-floor { grid-column: 1 / -1; position: relative; margin-block-start: 8px; }
.footer-floor canvas, .footer-floor img { position: absolute; display: block; }
.footer-floor img { inset: 0; inline-size: 100%; block-size: 100%; }
@media (max-width: 760px) {
  .footer { grid-template-columns: minmax(0, 1fr); padding-block-start: 44px; }
  .footer-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Section headings with a small animated mark beside them (marks.js), like Sai's globe on "Chip in". */
.mark-head { display: grid; grid-template-columns: 64px minmax(0, 1fr); align-items: center; gap: 18px; }
.mark-head > :is(h1, h2, h3) { margin: 0; font-size: 17px; font-weight: 500; color: var(--strong); }
.mark { display: grid; place-items: center; inline-size: 64px; block-size: 64px; }
.mark svg { inline-size: 40px; block-size: 40px; fill: none; stroke: var(--strong); stroke-width: 1.25; stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 1; overflow: visible; filter: url(#scribble); transition: transform 300ms var(--ease-out); }
.mark svg path { stroke-dasharray: 1; }
.mark svg .over { opacity: .5; }
/* Pointing at a section warms its mark to the logo's heat. */
.mark-head:hover .mark svg, .mark:hover svg { stroke: url(#heat-stroke); filter: url(#scribble) drop-shadow(0 0 6px #ff6a1f99); transform: rotate(-5deg) scale(1.06); }
.svg-defs { position: absolute; inline-size: 0; block-size: 0; overflow: hidden; }
@media (prefers-reduced-motion: reduce) { .mark svg { transition: none; } .mark-head:hover .mark svg, .mark:hover svg { transform: none; } }
.mark canvas { display: block; inline-size: 64px; block-size: 64px; }
