/* The ship: a person's own room laid over the whole page — its cabin (the world
   engine, #shipboard), the hologram's popups standing IN it (surfaces the engine
   lays on the world: .holo is their DOM), the world it flies to shown through its
   windscreen (#shipvoyage: a game's room page, laid behind the cabin and seen
   through the hole the windscreen punches), and the chat over all of it.

   The hologram is cozy, not neon: warm glass with a soft cyan edge, a rounded
   friendly face, light that looks projected — the cabin's lamps and the
   projector's glow, not a cockpit's. The same tokens dress the signed-out pages
   (.holoflat), so the catalog looks the same before and after signing in. */

:root {
  --holo-ink: #f3fbff;
  --holo-soft: rgba(233, 247, 255, .72);
  --holo-faint: rgba(233, 247, 255, .5);
  --holo-glass: rgba(20, 38, 54, .78);
  --holo-glass-deep: rgba(14, 28, 42, .76);
  --holo-edge: rgba(160, 232, 255, .58);
  --holo-edge-soft: rgba(160, 232, 255, .22);
  --holo-glow: 0 0 22px rgba(120, 214, 255, .28), 0 0 2px rgba(190, 240, 255, .6);
  --holo-warm: #ffd49a;
  --holo-coral: #ff9f86;
  --holo-teal: #6fe0d2;
  --holo-font: ui-rounded, "SF Pro Rounded", "Nunito", "Varela Round", system-ui, -apple-system, "Segoe UI", sans-serif;
}

/* ---- the page */
html.inship, html.inship body { margin: 0; height: 100%; overflow: hidden; background: #0c1122; }
html.inship #app { display: none; }
.shippage { position: fixed; inset: 0; background: #0c1122; color: var(--holo-ink); font-family: var(--holo-font); }
/* the world in the windscreen: a game's room page, BEHIND the cabin (its canvas draws nothing at the windscreen) */
.shipvoyage { position: fixed; inset: 0; z-index: 0; }
.shipvoyage .roompage { transform-origin: 0 0; will-change: transform, opacity; }
.shipvoyage .roompage.docked forji-chat, .shipvoyage .roompage.docked .roomlobby, .shipvoyage .roompage.docked .roomend, .shipvoyage .roompage.docked .ptbar, .shipvoyage .roompage.docked .pickwrap { display: none !important; }
.shipvoyage .roompage.docked, .shipvoyage .roompage.arriving { pointer-events: none; }
/* (a game seen as a portal, and flown into or out of, shows no labels: its names and tips are the game's own, drawn
   over its canvas a frame apart from it — they slide off what they name as the page is carried through the flight) */
.shipvoyage .roompage.docked :is(.dpw-pins, .dpt-pins, .dpw-pin, .dpt-pin, .dpw-panels), .shipvoyage .roompage.arriving :is(.dpw-pins, .dpt-pins, .dpw-pin, .dpt-pin, .dpw-panels) { visibility: hidden !important; }
.shipvoyage .roompage.arriving { opacity: 0; }
.shipworld { position: fixed; inset: 0; z-index: 1; transition: opacity .45s ease; }
.shipworld.away { opacity: 0; pointer-events: none; }
.shipworld.gone { visibility: hidden; }
/* (all of it: the engine sets its surfaces' own `visibility` and `pointer-events`, which would outvote the cabin's —
   and an unseen hologram would take the presses meant for the world in front) */
.shipworld.away *, .shipworld.gone * { pointer-events: none !important; }
.shipworld.gone * { visibility: hidden !important; }
.shipboard { position: absolute; inset: 0; }
/* the ship's chat: the overlay, over the cabin; out of the way while a world is in front */
.shippage forji-chat#ship-chat { --forji-glass: rgba(20, 28, 40, .72); transition: opacity .35s ease; }
.shippage forji-chat#ship-chat.away { opacity: 0; pointer-events: none; }
.shippage .shipvoyage forji-chat { transition: opacity .35s ease; }
/* a world's chat, seen from the ship: the hologram's glass — navy, a cyan hairline — not the site's charcoal */
.shippage forji-chat { --forji-glass: rgba(16, 26, 40, .66); }

/* ---- the hologram: popups floating round the person, a surface each (.holo is a surface's whole face) */
.holo { position: relative; width: 100%; height: 100%; font-family: var(--holo-font); color: var(--holo-ink); font-size: 15px; line-height: 1.4; -webkit-font-smoothing: antialiased; user-select: none; --fade: 1; }
.holo * { box-sizing: border-box; }
/* (the glass stands 16px inside its surface — holo.js GLOW — so its glow lies inside the surface, not cut off square) */
.holo .layer { position: absolute; inset: 16px; border-radius: 26px; background: var(--holo-glass); border: 1.5px solid var(--holo-edge); box-shadow: var(--holo-glow), inset 0 0 40px rgba(110, 200, 255, .12);
  /* (the cabin behind it softened, so its words read over a busy console) */
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  display: flex; flex-direction: column; overflow: hidden; transition: opacity .3s ease, filter .3s ease; }
/* light as projected: a soft sheen from the lens below, and the faintest lines across it */
.holo .layer::before { content: ""; position: absolute; inset: 0; pointer-events: none; border-radius: inherit;
  background: linear-gradient(to top, rgba(140, 225, 255, .16), transparent 45%), repeating-linear-gradient(to bottom, rgba(255, 255, 255, .025) 0 1px, transparent 1px 4px); }
.holo .layer.enter { animation: holo-in .42s cubic-bezier(.2, .8, .2, 1); }
@keyframes holo-in { from { opacity: 0; transform: translateY(18px) scale(.94); filter: blur(3px); } to { opacity: 1; transform: none; filter: none; } }
/* a card at the ring's edge fades as it goes round out of sight */
.holo.card { opacity: var(--fade); transition: opacity .2s ease; touch-action: none; }
.holo.headbar { touch-action: none; }
.holo .head { position: relative; display: flex; align-items: center; gap: 10px; padding: 14px 16px 10px; }
.holo .head .titles { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.holo .head h2 { margin: 0; font-size: 21px; font-weight: 700; letter-spacing: .01em; flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.holo .head .sub { color: var(--holo-soft); font-size: 14px; }
/* (a phone held up: the title keeps the line, what is said of it goes under it) */
.holo.tall .head { flex-wrap: wrap; row-gap: 2px; }
.holo.tall .head .sub { order: 3; flex-basis: 100%; }
.holo .body { position: relative; flex: 1; min-height: 0; overflow: auto; padding: 4px 16px 16px; scrollbar-width: thin; scrollbar-color: var(--holo-edge) transparent;
  /* (more below: the list fades out where it goes on, rather than being cut off by the popup's foot) */
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 26px), transparent); mask-image: linear-gradient(to bottom, #000 calc(100% - 26px), transparent); }
/* more below than is seen: a chevron at the body's foot, bobbing, gone at the end (holo.js hint) */
.holo .scrollhint { position: relative; height: 0; z-index: 2; display: flex; justify-content: center; pointer-events: none; opacity: 0; transition: opacity .25s ease; }
.holo .scrollhint.on { opacity: 1; }
.holo .scrollhint .icon, .holo .scrollhint i { position: absolute; bottom: 4px; width: 30px; height: 30px; border-radius: 50%; display: grid; place-items: center; font-size: 13px; color: var(--holo-ink);
  background: rgba(20, 38, 54, .9); border: 1.5px solid var(--holo-edge); box-shadow: var(--holo-glow); animation: holo-bob 1.6s ease-in-out infinite; }
@keyframes holo-bob { 50% { transform: translateY(3px); } }
.holo .foot { position: relative; display: flex; gap: 8px; padding: 10px 16px 14px; border-top: 1px solid var(--holo-edge-soft); flex-wrap: wrap; }
.holo .muted { color: var(--holo-soft); }
.holo .faint { color: var(--holo-faint); }
.holo p { margin: 0 0 10px; }
.holo .err { color: var(--holo-coral); font-weight: 600; margin: 6px 0; }

/* the rail of places: a row of lights floating over the projector, alone when the hologram is folded */
.holo.railbar { display: flex; align-items: center; justify-content: center; }
.holo .rail { display: flex; gap: 10px; padding: 10px 14px; border-radius: 26px; background: rgba(14, 28, 42, .42); border: 1px solid var(--holo-edge-soft); box-shadow: 0 0 24px rgba(120, 214, 255, .18);
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
.holo .rail button { position: relative; width: 58px; height: 58px; border-radius: 18px; border: 1.5px solid var(--holo-edge); background: var(--holo-glass-deep); color: var(--holo-ink); box-shadow: var(--holo-glow); display: grid; place-items: center; font-size: 23px; cursor: pointer; }
.holo .rail button.on { background: rgba(111, 224, 210, .28); border-color: var(--holo-teal); }
.holo .rail button .lbl { display: none; }
.holo.railbar.folded .rail { background: rgba(14, 28, 42, .55); }

/* buttons, fields, chips — soft and round */
.holo .hbtn { appearance: none; border: 1.5px solid var(--holo-edge); background: rgba(160, 232, 255, .12); color: var(--holo-ink); font: 600 14px/1 var(--holo-font); padding: 10px 16px; border-radius: 999px; cursor: pointer; display: inline-flex; align-items: center; gap: 8px; }
.holo .hbtn:hover { background: rgba(160, 232, 255, .24); }
.holo .hbtn.primary { background: linear-gradient(180deg, #ffe0a8, #ffbe78); border-color: #ffe7c2; color: #3a220f; box-shadow: 0 0 18px rgba(255, 190, 120, .45); }
.holo .hbtn.primary:hover { filter: brightness(1.05); }
.holo .hbtn.ghost { border-color: transparent; background: none; color: var(--holo-soft); }
.holo .hbtn.small { padding: 7px 12px; font-size: 13px; }
.holo .hbtn:disabled { opacity: .45; cursor: default; }
.holo .close { width: 34px; height: 34px; border-radius: 50%; padding: 0; justify-content: center; font-size: 16px; }
.holo input, .holo select { font: 15px var(--holo-font); color: var(--holo-ink); background: rgba(10, 22, 34, .6); border: 1.5px solid var(--holo-edge-soft); border-radius: 14px; padding: 9px 12px; width: 100%; outline: none; }
.holo input:focus { border-color: var(--holo-edge); box-shadow: 0 0 0 3px rgba(160, 232, 255, .15); }
.holo .chips { display: flex; flex-wrap: wrap; gap: 6px; }
.holo .chip { border: 1.5px solid var(--holo-edge-soft); background: rgba(160, 232, 255, .08); color: var(--holo-ink); border-radius: 999px; padding: 6px 12px; font: 600 13px var(--holo-font); cursor: pointer; }
.holo .chip.on { border-color: var(--holo-warm); background: rgba(255, 212, 154, .2); color: #fff4e2; }
.holo .row { display: flex; gap: 10px; align-items: center; }
.holo .grow { flex: 1; min-width: 0; }
.holo .list { display: flex; flex-direction: column; gap: 8px; }
.holo .item { display: flex; align-items: center; gap: 12px; padding: 10px 12px; border-radius: 16px; background: rgba(160, 232, 255, .07); border: 1px solid var(--holo-edge-soft); cursor: pointer; }
.holo .item:hover { background: rgba(160, 232, 255, .14); }
.holo .item .thumb { width: 54px; height: 54px; border-radius: 14px; object-fit: cover; flex: none; }
.holo .item b { display: block; font-size: 15px; }
.holo .item .muted { font-size: 14px; }
.holo .badge { font: 700 11px var(--holo-font); letter-spacing: .04em; text-transform: uppercase; padding: 3px 8px; border-radius: 999px; background: var(--holo-warm); color: #3a220f; }
.holo .badge.teal { background: var(--holo-teal); color: #0c2b28; }
.holo .av { width: 34px; height: 34px; border-radius: 50%; display: inline-grid; place-items: center; font: 700 13px var(--holo-font); overflow: hidden; flex: none; }
.holo .av:not(.face) img { width: 100%; height: 100%; object-fit: cover; }
.holo .av.lg { width: 56px; height: 56px; font-size: 20px; }

/* ---- the worlds: the catalog's bar over the ring (its search, its turners), and a card a world on the ring */
.holo.headbar .layer { border-radius: 999px; flex-direction: row; }
.holo.headbar .head { flex: 1; min-width: 0; padding: 0 10px 0 22px; height: 100%; }
.holo.headbar .head h2 { font-size: 19px; flex: none; }
/* (the bar's title keeps its words; what is said of it gives way first) */
.holo.headbar .head .sub { white-space: nowrap; flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.holo.headbar .head .hbtn { flex: none; white-space: nowrap; }
.holo .head .find { width: 170px; flex: none; padding: 7px 12px; font-size: 14px; border-radius: 999px; }
.holo .head:has(.find) h2 { flex: none; }
/* a row's dots, on its bar: a dot a card, the ones in view lit (holo.js placeRing) */
.holo .rowdots { display: inline-flex; align-items: center; gap: 7px; flex: none; margin: 0 6px; }
.holo .rowcount { flex: none; margin: 0 8px; color: var(--holo-soft); font-size: 14px; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* (a crowded bar: the search gives way before a button is pushed off its end) */
.holo.headbar .head .find { flex: 0 1 170px; min-width: 96px; }
.holo.headbar .head .close { flex: none; }
.holo .rowdots .rdot { width: 9px; height: 9px; padding: 0; border-radius: 50%; border: 0; background: var(--holo-edge-soft); cursor: pointer; transition: background .2s ease, transform .2s ease; }
.holo .rowdots .rdot.on { background: var(--holo-ink); transform: scale(1.15); }
/* and an arrow at each of its ends: a round glowing button, the way to more */
.holo.rowarrow { display: grid; }
.holo.rowarrow .turners { position: absolute; inset: 16px; display: grid; }
.holo.rowarrow button { width: 100%; height: 100%; border-radius: 50%; border: 1.5px solid var(--holo-edge); background: var(--holo-glass); color: var(--holo-ink); box-shadow: var(--holo-glow);
  font-size: 22px; display: grid; place-items: center; cursor: pointer; -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
.holo.rowarrow button:hover { background: rgba(160, 232, 255, .24); }
/* (a phone held up: no room on the bar for a search — the chat finds a world by name) */
.holo.tall .head .find { display: none; }
.holo.tall.headbar .head .sub { display: none; }
.holo .wcard { display: flex; flex-direction: column; cursor: pointer; transition: border-color .2s ease, box-shadow .2s ease, opacity .3s ease, filter .3s ease; }
.holo .wcard:hover { border-color: #cdf1ff; box-shadow: 0 0 30px rgba(140, 225, 255, .45), 0 0 2px rgba(190, 240, 255, .8); }
/* the projector's light on it: a warm-cyan haze up from its foot */
.holo .wcard::after { content: ""; position: absolute; inset: auto -20% -10% -20%; height: 45%; pointer-events: none;
  background: radial-gradient(ellipse at 50% 100%, rgba(120, 214, 255, .22), transparent 70%); }
.holo .wcard .cover { position: relative; aspect-ratio: 16 / 10; flex: none; display: grid; place-items: center; overflow: hidden;
  background: radial-gradient(ellipse at 30% 20%, rgba(255, 200, 150, .16), transparent 60%), radial-gradient(ellipse at 80% 90%, rgba(120, 200, 255, .16), transparent 55%), rgba(8, 14, 30, .7); }
.holo .wcard .cover img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; -webkit-user-drag: none; }
/* a world with no cover: its galaxy — a warm heart, two arms of its hue wound round it, seen a little tilted */
.holo .wcard .cover .galaxy { position: relative; border-radius: 50%; transform: rotate(var(--spin, 20deg)) scaleY(.62);
  background: radial-gradient(circle, #fffaf0 0 4%, #ffe2b0 9%, transparent 30%),
    repeating-conic-gradient(from 0deg, transparent 0 22deg, color-mix(in srgb, var(--g1) 55%, transparent) 60deg, transparent 110deg 180deg),
    radial-gradient(circle, color-mix(in srgb, var(--g2) 45%, transparent), transparent 70%);
  -webkit-mask: radial-gradient(circle, #000 25%, transparent 70%); mask: radial-gradient(circle, #000 25%, transparent 70%);
  filter: blur(.6px) drop-shadow(0 0 10px var(--g1)); }
.holo .wcard .tag { position: absolute; top: 8px; right: 8px; }
.holo .wcard .lock { position: absolute; top: 8px; left: 8px; width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center; background: rgba(12, 17, 34, .8); font-size: 12px; }
.holo .wcard .wtext { padding: 9px 12px 10px; display: flex; flex-direction: column; gap: 3px; flex: 1; min-height: 0; }
.holo .wcard .wtext b { font-size: 15px; line-height: 1.2; }
.holo .wcard .wtext .muted { font-size: 13px; line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.holo .wcard .wtext .fact { align-self: flex-start; margin-top: auto; font-size: 12px; padding: 2px 8px; }
/* a tray's card: a link to its page — its picture, what it is; the markers' card a glyph for a picture */
.holo .tcard { color: inherit; text-decoration: none; }
.holo .tcard .cover img { object-fit: contain; padding: 10px; }
.holo .tcard .wtext .muted { -webkit-line-clamp: 3; }
.holo .tcard .glyph { font-size: 44px; color: var(--holo-warm); text-shadow: 0 0 18px rgba(255, 190, 120, .5); }
.holo .wcard.here { border-color: var(--holo-teal); }
.holo .wcard.turn { animation: planet-turn 1.6s ease-in-out infinite; }
@keyframes planet-turn { 50% { box-shadow: 0 0 0 3px var(--holo-warm), 0 0 28px rgba(255, 212, 154, .8); } }
.holo .wcard.locked { cursor: default; }
.holo .wcard.locked .cover, .holo .wcard.locked .wtext { opacity: .45; filter: grayscale(.6); }
.holo .wcard.locked:hover { border-color: var(--holo-edge); box-shadow: var(--holo-glow); }
/* (a world's page open over the ring: the other cards wait, dim, out of the hand's way) */
.holo .wcard.behind { pointer-events: none; opacity: .4; filter: saturate(.6); }

/* ---- a game's page on the hologram */
.holo .intro { display: flex; gap: 14px; align-items: flex-start; }
.holo .intro > img { width: 128px; height: 128px; border-radius: 14px; object-fit: cover; flex: none; }
.holo .intro p { margin: 0; }
.holo .gallery { display: flex; gap: 8px; overflow-x: auto; margin: 10px -2px 0; padding-bottom: 4px; }
.holo .gallery img { height: 150px; border-radius: 14px; flex: none; }
.holo .facts { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 10px; }
.holo .fact { font: 600 13px var(--holo-font); padding: 4px 10px; border-radius: 999px; background: rgba(160, 232, 255, .1); border: 1px solid var(--holo-edge-soft); color: var(--holo-soft); }
.holo .ways { display: grid; gap: 8px; margin-top: 8px; }
.holo .way { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-radius: 16px; border: 1.5px solid var(--holo-edge-soft); background: rgba(160, 232, 255, .06); }
.holo .way .what { flex: 1; min-width: 0; }
/* who sits at a way to play: faces overlapping a little, you first */
.holo .way .seats { display: flex; flex: none; }
.holo .way .seats .av { width: 30px; height: 30px; font-size: 11px; border: 2px solid rgba(12, 22, 36, .9); }
.holo .way .seats .av + .av { margin-left: -8px; }
.holo .way .seats .av.open { border: 2px dashed var(--holo-edge-soft); background: transparent; color: var(--holo-soft); }
.holo .way .what b { display: block; }
.holo .way .what span { color: var(--holo-soft); font-size: 13px; }

/* ---- the wardrobe: one popup — the looks in a grid, the colours of the one worn, the name */
.holo .looks { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 8px; }
.holo .look { appearance: none; display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 10px 4px 8px; border-radius: 16px; border: 1.5px solid var(--holo-edge-soft); background: rgba(160, 232, 255, .06); color: var(--holo-ink); font: 700 13px var(--holo-font); text-align: center; cursor: pointer; transition: background .2s ease, border-color .2s ease; }
.holo .look:hover { background: rgba(160, 232, 255, .14); }
.holo .look .mono { width: 48px; height: 48px; border-radius: 50%; display: grid; place-items: center; font-size: 19px; color: #fff; box-shadow: 0 0 14px rgba(0, 0, 0, .25); }
/* a look's portrait (the engine's own drawing of it, transparent round it): standing on a soft pool of light */
.holo .look .portrait { width: 84px; height: 84px; margin: -6px 0 -4px; object-fit: contain; background: radial-gradient(ellipse 60% 22% at 50% 88%, rgba(160, 232, 255, .22), transparent 70%); -webkit-user-drag: none; }
.holo .looks:has(.portrait) { grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); }
.holo .chip.skin { display: inline-flex; align-items: center; gap: 4px; padding-left: 4px; }
.holo .chip.skin { flex: none; }
.holo .chip.skin .portrait { width: 24px; height: 24px; object-fit: contain; margin: -3px 0; }
.holo .look .lname { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.holo .look.on { background: rgba(255, 212, 154, .18); border-color: var(--holo-warm); }
/* (one line, never wrapping over the grid: more colours than fit slide sideways) */
.holo .skins { position: relative; flex: none; display: flex; align-items: center; gap: 12px; padding: 10px 16px; border-top: 1px solid var(--holo-edge-soft); }
.holo .skins > .muted { flex: none; }
.holo .skins .chips { flex-wrap: nowrap; overflow-x: auto; min-width: 0; scrollbar-width: none; padding: 2px; }
.holo .skins .chips.more { -webkit-mask-image: linear-gradient(to right, #000 80%, transparent); mask-image: linear-gradient(to right, #000 80%, transparent); }
.holo .skins .skinsmore { flex: none; padding: 6px 9px; }
.holo .skins .skinsmore[hidden] { display: none; }

/* ---- the tour's words, and the rail's key */
.holo .tourstep { font-size: 16px; line-height: 1.45; }
.holo .railkey { display: grid; grid-template-columns: 1fr; gap: 6px; margin-top: 4px; }
.holo .rk { display: flex; align-items: center; gap: 10px; }
.holo .rk .rki { width: 36px; height: 36px; border-radius: 12px; flex: none; display: grid; place-items: center; border: 1.5px solid var(--holo-edge-soft); background: var(--holo-glass-deep); font-size: 15px; }
.holo .rk b { display: block; font-size: 14px; }
.holo .rk .muted { font-size: 12.5px; }
.holo .dots { display: flex; gap: 6px; margin: 8px 0 12px; }
.holo .dots i { width: 9px; height: 9px; border-radius: 50%; background: var(--holo-edge-soft); }
.holo .dots i.done { background: var(--holo-teal); }
.holo .dots i.now { background: var(--holo-warm); box-shadow: 0 0 10px var(--holo-warm); }

/* ---- the portals: the games its person is in, floating round the ship. The one in the windscreen is its live
   page (voyage.js), cut to a soft ROUND window that dissolves to nothing at its edge — space dissolving into it the
   same way (a soft warp hole, voyage.js holeOf) — the others their covers; round each, wisps of light turning in the
   band where they meet. Round whatever the page's shape: a circle `closest-side` (half the page's height), its
   `--portal-r` share of the height across; opened out past the page's corners (--portal-r 110%) as it is flown into. */
@property --portal-r { syntax: "<percentage>"; inherits: false; initial-value: 48%; }
@property --portal-a { syntax: "<angle>"; inherits: false; initial-value: 0deg; }
@property --portal-b { syntax: "<angle>"; inherits: false; initial-value: 0deg; }
.shipvoyage .roompage.portal {
  -webkit-mask-image: radial-gradient(circle closest-side at 50% 50%, #000 calc(var(--portal-r) * 1.4), rgba(0, 0, 0, .55) calc(var(--portal-r) * 1.72), transparent calc(var(--portal-r) * 2));
  mask-image: radial-gradient(circle closest-side at 50% 50%, #000 calc(var(--portal-r) * 1.4), rgba(0, 0, 0, .55) calc(var(--portal-r) * 1.72), transparent calc(var(--portal-r) * 2)); }
.portalcover { position: absolute; inset: 0; background: #0b1026 center / cover no-repeat;
  -webkit-mask-image: radial-gradient(circle closest-side at 50% 50%, #000 67%, rgba(0, 0, 0, .55) 82.5%, transparent 96%);
  mask-image: radial-gradient(circle closest-side at 50% 50%, #000 67%, rgba(0, 0, 0, .55) 82.5%, transparent 96%); }
/* the live portal's own cover: over its page while that has no game to show (still gathering, still loading) */
.portalcover.wait { opacity: 0; transition: opacity .6s ease; }
.portalcover.wait.on { opacity: 1; }
.portalrim { position: absolute; inset: 0; pointer-events: none; }
.portalrim::before, .portalrim::after { content: ""; position: absolute; inset: 0; filter: blur(10px);
  -webkit-mask-image: radial-gradient(circle closest-side at 50% 50%, transparent 62.5%, #000 78.5%, rgba(0, 0, 0, .6) 88%, transparent 98%);
  mask-image: radial-gradient(circle closest-side at 50% 50%, transparent 62.5%, #000 78.5%, rgba(0, 0, 0, .6) 88%, transparent 98%); }
.portalrim::before { animation: portal-turn 17s linear infinite;
  background: conic-gradient(from var(--portal-a), rgba(150, 225, 255, 0), rgba(150, 225, 255, .55) 40deg, rgba(190, 170, 255, 0) 110deg, rgba(255, 214, 170, .4) 175deg, rgba(150, 225, 255, 0) 240deg, rgba(170, 240, 255, .5) 305deg, rgba(150, 225, 255, 0)); }
.portalrim::after { animation: portal-turn-back 26s linear infinite; opacity: .7;
  background: conic-gradient(from var(--portal-b), rgba(210, 180, 255, 0), rgba(210, 180, 255, .45) 70deg, rgba(150, 225, 255, 0) 150deg, rgba(160, 240, 230, .4) 250deg, rgba(210, 180, 255, 0) 330deg); }
@keyframes portal-turn { to { --portal-a: 360deg; } }
@keyframes portal-turn-back { to { --portal-b: -360deg; } }
/* the ripples: rings of light running out through the rim's band, one after another, fading as they go (inside the
   portal's box — the surface clips what is past it — and seen where space dissolves into it) */
.portalrim .ripple { position: absolute; left: 50%; top: 50%; height: 97%; aspect-ratio: 1; translate: -50% -50%; border-radius: 50%;
  background: radial-gradient(circle closest-side, transparent 84%, rgba(170, 236, 255, .7) 92%, rgba(205, 185, 255, .35) 96%, transparent 100%);
  filter: blur(1.5px); opacity: 0; animation: portal-ripple 4s cubic-bezier(.25, .6, .4, 1) infinite; }
.portalrim .ripple:nth-child(2) { animation-delay: -.8s; }
.portalrim .ripple:nth-child(3) { animation-delay: -1.6s; }
.portalrim .ripple:nth-child(4) { animation-delay: -2.4s; }
.portalrim .ripple:nth-child(5) { animation-delay: -3.2s; }
.portalrim .ripple:nth-child(even) { background: radial-gradient(circle closest-side, transparent 86%, rgba(255, 220, 180, .45) 93%, rgba(170, 236, 255, .3) 97%, transparent 100%); }
@keyframes portal-ripple { 0% { scale: .6; opacity: 0; } 20% { opacity: .85; } 100% { scale: 1; opacity: 0; } }
/* your turn there: a cyan ring in the rim's band, pulsing with the sign's "Your turn" (kept inside the box: the
   surface clips what is past it) */
.portalrim .pulse { position: absolute; left: 50%; top: 50%; height: 100%; aspect-ratio: 1; translate: -50% -50%; border-radius: 50%; opacity: 0;
  background: radial-gradient(circle closest-side, transparent 60%, rgba(70, 225, 255, .55) 70%, rgba(90, 235, 255, 1) 79%, rgba(70, 225, 255, .5) 88%, transparent 97%);
  filter: blur(4px); }
.turn > .portalrim .pulse { animation: portal-pulse 1.6s ease-in-out infinite; }
@keyframes portal-pulse { 0%, 100% { opacity: .3; scale: .95; } 50% { opacity: 1; scale: 1; } }

/* ---- the windscreen's own sign: the world out there, and whose turn it is */
.wsign { font-family: var(--holo-font); color: #fff7ea; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 2px; width: 100%; height: 100%; box-sizing: border-box; cursor: pointer; text-align: center; }
/* (the words stand in the strip over the portal: the rest of the sign is the portal, pressed to fly there) */
.wsign::after { content: ""; flex: 0 0 calc(100% - var(--strip, 25%) - 6%); }
.wsign .pname { font: 700 30px/1.1 var(--holo-font); letter-spacing: .01em; text-shadow: 0 0 12px rgba(255, 190, 120, .55), 0 2px 4px rgba(0, 0, 0, .8); white-space: nowrap; }
.wsign .pturn { font: 700 15px/1.1 var(--holo-font); color: var(--holo-warm, #ffd49a); text-transform: uppercase; letter-spacing: .08em; text-shadow: 0 1px 3px rgba(0, 0, 0, .8); animation: sign-turn 1.6s ease-in-out infinite; }
@keyframes sign-turn { 50% { opacity: .55; } }

/* the hologram's icons (Font Awesome solid, the app's own face) */
.fa-earth-americas::before { content: "\f57d"; } .fa-shirt::before { content: "\f553"; } .fa-user-group::before { content: "\f500"; }
.fa-dice::before { content: "\f522"; } .fa-user::before { content: "\f007"; } .fa-shield-halved::before { content: "\f3ed"; }
.fa-wand-magic-sparkles::before { content: "\e2ca"; } .fa-rocket::before { content: "\f135"; } .fa-arrow-left::before { content: "\f060"; }
.fa-magnifying-glass::before { content: "\f002"; } .fa-play::before { content: "\f04b"; } .fa-lock::before { content: "\f023"; }
.fa-star::before { content: "\f005"; } .fa-print::before { content: "\f02f"; } .fa-check::before { content: "\f00c"; }
.fa-right-from-bracket::before { content: "\f2f5"; } .fa-plus::before { content: "\f067"; } .fa-list::before { content: "\f03a"; }
.fa-link::before { content: "\f0c1"; } .fa-robot::before { content: "\f544"; } .fa-users::before { content: "\f0c0"; } .fa-forward::before { content: "\f04e"; }
.fa-chevron-left::before { content: "\f053"; } .fa-chevron-right::before { content: "\f054"; } .fa-chevron-down::before { content: "\f078"; }

/* ---- a card over the whole page (a guest's lobby, the ship's sign-in wall) */
.holoflat { font-family: var(--holo-font); }

/* ---- the signed-out pages (html.holoflat): the site's own pages — the catalog, a game, the trays, the sign-in
   door, a guest's card — flat, but in the hologram's light: the night outside the ship, warm glass for panels,
   posters that glow as the planets do. The site's tokens are the hologram's here, so every page follows. */
html.holoflat {
  color-scheme: dark;
  --bg: #0c1122; --panel: rgba(24, 44, 60, .58); --ink: #f3fbff; --muted: rgba(233, 247, 255, .66); --line: rgba(160, 232, 255, .22);
  --accent: #ffc98a; --accent-ink: #3a220f; --danger: #ff9f86; --soft: rgba(160, 232, 255, .1); --gold: #ffd49a;
}
html.holoflat body { font-family: var(--holo-font); background: #0c1122; color: var(--holo-ink);
  background-image: radial-gradient(ellipse 80% 50% at 20% 0%, rgba(255, 190, 130, .1), transparent 70%), radial-gradient(ellipse 70% 60% at 90% 100%, rgba(110, 200, 255, .12), transparent 70%),
    radial-gradient(1px 1px at 12% 18%, rgba(255, 255, 255, .7), transparent 60%), radial-gradient(1px 1px at 68% 34%, rgba(255, 255, 255, .55), transparent 60%),
    radial-gradient(1.5px 1.5px at 42% 72%, rgba(255, 240, 220, .6), transparent 60%), radial-gradient(1px 1px at 86% 12%, rgba(255, 255, 255, .5), transparent 60%),
    radial-gradient(1px 1px at 24% 88%, rgba(210, 240, 255, .55), transparent 60%), radial-gradient(1.5px 1.5px at 94% 58%, rgba(255, 255, 255, .45), transparent 60%);
  background-attachment: fixed; }
html.holoflat .topbar { background: rgba(12, 17, 34, .72); border-bottom-color: var(--line); backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px); }
html.holoflat .topbar .brand { font-weight: 800; letter-spacing: .01em; }
html.holoflat .topbar .brand::before { content: ""; display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: 8px; vertical-align: 1px;
  background: radial-gradient(circle at 35% 35%, #ffe7c2, #ff9f6a); box-shadow: 0 0 10px rgba(255, 190, 120, .8); }
html.holoflat .topbar nav a.signin { border-color: var(--holo-edge); box-shadow: var(--holo-glow); border-radius: 999px; }
html.holoflat .sitefoot { background: transparent; }
html.holoflat .hero h1 { font-size: clamp(34px, 5vw, 54px); font-weight: 800; letter-spacing: -.01em; text-shadow: 0 0 30px rgba(160, 232, 255, .25); }
/* the landing: the pitch beside a photograph of the ship, then how it works in four pictures */
.hero.landing { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); gap: 28px; align-items: center; }
.hero.landing h1 { margin-top: 0; }
.hero.landing .hshot { width: 100%; aspect-ratio: 16 / 10; object-fit: cover; border-radius: 22px; border: 1.5px solid var(--holo-edge, rgba(160, 232, 255, .4)); box-shadow: 0 0 40px rgba(110, 200, 255, .22); }
.how { margin-top: 44px; }
/* (two to a row: a picture wide enough that the hologram's words on it can be read) */
.how .steps { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 22px; }
.how .step { display: flex; flex-direction: column; border-radius: 20px; overflow: hidden; background: var(--holo-glass, rgba(24, 44, 60, .58)); border: 1.5px solid var(--holo-edge-soft, rgba(160, 232, 255, .22)); }
.how .step img { width: 100%; aspect-ratio: 16 / 10; object-fit: cover; display: block; }
.how .step .stext { padding: 12px 14px 16px; }
.how .step b { font-size: 17px; }
.how .step p { margin: 6px 0 0; color: var(--muted); line-height: 1.5; font-size: 14.5px; }
@media (max-width: 760px) { .hero.landing { grid-template-columns: 1fr; } .hero.landing .hshot { order: -1; } .how .steps { grid-template-columns: 1fr; } }
html.holoflat .btn:where(:not(#stage *)) { border-radius: 999px; background: linear-gradient(180deg, #ffe0a8, #ffbe78); border-color: #ffe7c2; color: #3a220f; box-shadow: 0 0 18px rgba(255, 190, 120, .35); font-weight: 700; }
html.holoflat .btn.secondary:where(:not(#stage *)) { background: rgba(160, 232, 255, .1); border-color: var(--holo-edge); color: var(--holo-ink); box-shadow: none; }
html.holoflat .panel, html.holoflat .card.wall { background: var(--holo-glass); border: 1.5px solid var(--holo-edge); border-radius: 22px; box-shadow: var(--holo-glow); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }
html.holoflat .card:where(:not(#stage *)) .poster { border-radius: 18px; border: 1.5px solid var(--holo-edge-soft); box-shadow: 0 0 0 transparent; transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease; }
html.holoflat .card:where(:not(#stage *)):hover .poster { border-color: var(--holo-edge); box-shadow: var(--holo-glow); }
html.holoflat .card:where(:not(#stage *)) h3 { font-weight: 750; }
html.holoflat .card:where(:not(#stage *)) .seats { background: rgba(12, 17, 34, .78); color: var(--holo-ink); border: 1px solid var(--holo-edge-soft); }
html.holoflat .pill:where(:not(#stage *)) { border-color: var(--holo-edge-soft); color: var(--holo-soft); }
html.holoflat .gart, html.holoflat .gallery img { border-radius: 18px; border: 1.5px solid var(--holo-edge-soft); }
html.holoflat input:where(:not(#stage *)), html.holoflat select:where(:not(#stage *)), html.holoflat textarea:where(:not(#stage *)) { background: rgba(10, 22, 34, .6); color: var(--holo-ink); border: 1.5px solid var(--holo-edge-soft); border-radius: 14px; }
html.holoflat .err { color: var(--holo-coral); }

/* a world's lobby, seen from the ship: the hologram's glass, not the site's flat card */
.shipvoyage .card.wall.endcard { background: var(--holo-glass-deep); border: 1.5px solid var(--holo-edge); border-radius: 22px; box-shadow: var(--holo-glow); color: var(--holo-ink); font-family: var(--holo-font); -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); }
.shipvoyage .endcard .btn:not(.secondary) { border-radius: 999px; background: linear-gradient(180deg, #ffe0a8, #ffbe78); border-color: #ffe7c2; color: #3a220f; box-shadow: 0 0 18px rgba(255, 190, 120, .35); }
.shipvoyage .endcard .btn.secondary { border-radius: 999px; background: rgba(160, 232, 255, .1); border-color: var(--holo-edge); color: var(--holo-ink); }
.shipvoyage .card.wall.lobbycard { background: var(--holo-glass-deep); border: 1.5px solid var(--holo-edge); border-radius: 22px; box-shadow: var(--holo-glow); color: var(--holo-ink); font-family: var(--holo-font);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); }
.shipvoyage .lobbycard .btn:not(.secondary) { border-radius: 999px; background: linear-gradient(180deg, #ffe0a8, #ffbe78); border-color: #ffe7c2; color: #3a220f; box-shadow: 0 0 18px rgba(255, 190, 120, .35); }
.shipvoyage .lobbycard .btn.secondary { border-radius: 999px; background: rgba(160, 232, 255, .1); border-color: var(--holo-edge); color: var(--holo-ink); }
.shipvoyage .lobbycard .codebox { background: rgba(160, 232, 255, .08); border-radius: 14px; }
