/* SPDX-License-Identifier: LicenseRef-Proprietary */
@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../assets/fonts/ibm-plex-sans-latin-400-normal.woff2") format("woff2");
}

@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("../assets/fonts/ibm-plex-sans-latin-600-normal.woff2") format("woff2");
}

@font-face {
  font-family: "IBM Plex Sans";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("../assets/fonts/ibm-plex-sans-latin-700-normal.woff2") format("woff2");
}

@font-face {
  font-family: "Press Start 2P";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("../assets/fonts/press-start-2p-latin-400-normal.woff2") format("woff2");
}

* { box-sizing: border-box; }

/* A jump to an anchor, and a focus that scrolls, stop below the sticky header on any page. The margin
   of the target is used and not the padding of the page, which would also shift the progress of the
   scenes on the scroll. Only the content and the footer have it: a control in the sticky header that
   gets the focus back would scroll the page. */
main[id], main [id], main :focus-visible, .site-footer :focus-visible { scroll-margin-top: var(--header-height, var(--space-72)); }

body {
  margin: 0;
  min-height: 100vh;
  font: var(--font-body);
  background: var(--bg);
  color: var(--text);
}
/* The glow of tokens.css does not move while the page scrolls, so it lights the top of the window on
   a long page as on a short one. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: var(--layer-behind);
  background: var(--page-glow);
  pointer-events: none;
}

h1, h2, h3, p { margin: 0; }

[hidden] { display: none !important; }
dialog:not([open]) { display: none; }

.muted { color: var(--muted); }

button:focus-visible, a:focus-visible, input:focus-visible, [tabindex="0"]:focus-visible {
  outline: var(--focus-width) solid var(--focus);
  outline-offset: var(--focus-offset);
}

.card {
  background: var(--surface);
  border: var(--border-1) solid var(--line);
  border-radius: var(--radius);
  padding: var(--card-pad);
}

.btn {
  display: inline-block;
  min-height: var(--target-min);
  text-decoration: none;
  cursor: pointer;
}


/* A sprite of characters.js shows one frame of its file. Each place sets a width of --sprite-size
   times or divided by a power of two, so every pixel of the art of the tallest character covers the
   same number of pixels on screen. A standing figure scales the frames of every other character by
   his height. Each frame is square, so the full height of the picture shows one frame. A strip
   shows its frames one after another while the system allows motion, over and over, or
   --strip-rounds times after --strip-delay where a place sets them, and else --autoplay-rounds times, and
   then rests: a strip does not loop for ever. A strip with a rest frame shows that frame and plays its frames
   only where a look starts it, once. */
.character-sprite { width: var(--sprite-size); aspect-ratio: 1; overflow: hidden; }
.character-sprite img {
  display: block;
  width: auto;
  max-width: none;
  height: 100%;
  image-rendering: pixelated;
}
@media (prefers-reduced-motion: no-preference) {
  .character-sprite-strip:not(.character-sprite-once) img {
    animation: sprite-frames calc(var(--frames) * var(--sprite-frame-time)) steps(var(--frames)) var(--strip-delay, var(--duration-0)) var(--strip-rounds, var(--autoplay-rounds)) backwards;
  }
}
.character-sprite-once img { transform: translateX(calc(-100% * var(--rest-frame) / var(--frames))); }
@keyframes sprite-frames { from { transform: none; } to { transform: translateX(-100%); } }

/* A character styled by standingFigureStyle in characters.js. His frames are --frame-width wide:
   --width times --frame-scale, so each character stands at his height, times --pose-scale, so each
   sprite shows him at one size. His figure, between --figure-left and --figure-right percent of the
   picture, is --figure-width wide. standingFigure gives the class standing-figure, and a place that
   only measures a figure gives the class figure-size. */
.standing-figure, .figure-size {
  --frame-width: calc(var(--width) * var(--frame-scale) * var(--pose-scale));
  --figure-width: calc((var(--figure-right) - var(--figure-left)) * var(--frame-width) / 100);
}
/* A character standing beside others covers only the width of his figure in a row, and stands with
   the bottom edge of his figure, --figure-bottom percent down the picture, on the bottom of the
   row, so the empty edges of a sprite frame do not open a gap and every character stands on one
   floor. */
.standing-figure {
  margin-inline: calc(var(--figure-left) * var(--frame-width) / -100) calc((100 - var(--figure-right)) * var(--frame-width) / -100);
  margin-bottom: calc((100 - var(--figure-bottom)) * var(--frame-width) / -100);
}
.standing-figure .character { width: var(--frame-width); }

/* The pixel sprites of Shelly and Jack are drawn for a dark background, and parts of their edge, such
   as the white tail of Jack, are as light as the light theme. So in the light theme they get a dark
   outline on every page. */
:root[data-theme="light"] .character {
  filter: var(--character-outline);
}

.share-status { font: var(--font-small); color: var(--text-2); overflow-wrap: anywhere; }
.share-status:empty { display: none; }

/* Read by screen readers and not shown. */
.sr-only {
  position: absolute;
  width: var(--space-1);
  height: var(--space-1);
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* --- The header, the same on the homepage and the legal pages, and the footer of every page --- */

/* The header sets its own font, so it has the same height on every page. */
.nav {
  position: var(--header-position);
  top: 0;
  z-index: var(--layer-header);
  display: flex;
  align-items: center;
  gap: var(--space-16);
  padding-block: var(--header-pad);
  background: color-mix(in oklab, var(--bg) 88%, transparent);
  border-bottom: var(--border-1) solid var(--line);
  backdrop-filter: blur(var(--blur-nav));
  font: var(--font-nav);
}
/* site-header.js sets .scrolled while the page is scrolled down. */
.nav.scrolled { box-shadow: var(--shadow-nav); }
.logo {
  display: flex;
  align-items: center;
  min-height: var(--target-min);
  font: 700 var(--font-20)/var(--leading-100) var(--sans);
  color: var(--text);
  text-decoration: none;
}
.nav-links { display: flex; gap: var(--space-20); }
.nav-links a { display: flex; align-items: center; min-height: var(--target-min); color: var(--text-2); text-decoration: none; }
.nav-links a:hover { color: var(--text); }
.icon-button {
  display: grid;
  place-items: center;
  width: var(--size-icon-button);
  height: var(--size-icon-button);
  padding: 0;
  border: var(--border-1) solid var(--line-strong);
  border-radius: var(--radius-8);
  background: transparent;
  color: var(--text);
  cursor: pointer;
}
.menu-button { display: none; }
.settings-button { margin-left: auto; }

/* One column for each group of links, and the copyright below them. Leaves room at the bottom for
   the traps that open along the bottom edge. The footer sets its fonts, so it looks the same on every
   page. */
.site-footer {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, max-content));
  gap: var(--space-24) var(--space-48);
  padding-block: var(--space-40) var(--footer-room);
  border-top: var(--border-1) solid var(--line);
  color: var(--muted);
  font: var(--font-small);
}
.site-footer h2 { margin-bottom: var(--space-8); color: var(--text); font: var(--font-small); font-weight: 600; }
.site-footer ul { display: grid; gap: var(--space-6); margin: 0; padding: 0; list-style: none; }
.site-footer a { display: var(--footer-link-display); align-items: center; min-height: var(--target-min); color: inherit; text-decoration: var(--link-decoration); }
.site-footer a:hover { color: var(--text); text-decoration: underline; }
.copyright, .other-look, .footer-languages { grid-column: 1 / -1; }
.footer-languages { display: none; }
/* A link that stands alone in a card is a target of its own. */
.timeline-card a, .trust-fact a, .level-case { min-height: var(--target-min); align-content: center; }

/* --- Layout of the homepage --- */

.section {
  --layout-gap: var(--space-16);
  padding: var(--section-pad) 0;
}

/* --- Traps --- */

/* A trap is a dialog opened with show(). Each kind below places it on the page. */
.trap {
  position: fixed;
  inset: auto;
  z-index: var(--layer-trap);
  width: auto;
  margin: 0;
  color: var(--text);
  background: var(--surface);
  border: var(--border-1) solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-trap);
}
@keyframes slide-up { from { transform: translateY(var(--space-24)); opacity: 0; } }

.trap-close {
  margin-left: auto;
  background: none;
  border: 0;
  color: var(--muted);
  font-size: var(--font-24);
  line-height: var(--leading-100);
  cursor: pointer;
  padding: var(--space-4) var(--space-8);
}
.trap-quiet {
  background: none;
  border: 0;
  color: var(--muted);
  font: 400 var(--font-14)/var(--leading-140) var(--sans);
  text-decoration: underline;
  cursor: pointer;
  padding: var(--space-8) 0;
}
.trap-bait {
  background: var(--jack-purple);
  color: var(--on-jack);
  border: 0;
  padding: var(--space-14) var(--space-24);
  font: 700 var(--font-16)/var(--leading-100) var(--sans);
  cursor: pointer;
}
.trap-actions { --layout-gap: var(--space-20); }

.trap-cookies {
  left: var(--space-16);
  right: var(--space-16);
  bottom: var(--space-16);
  max-width: var(--width-trap-cookies);
  margin: 0 auto;
  padding: var(--space-20);
  display: grid;
  gap: var(--space-12);
}
.file-chip {
  justify-self: start;
  font: 600 var(--font-14)/var(--leading-100) var(--sans);
  color: var(--text-2);
  background: var(--bg);
  border: var(--border-1) solid var(--line);
  border-radius: var(--radius-6);
  padding: var(--space-8) var(--space-10);
}

.trap-promo {
  top: var(--trap-top);
  left: var(--space-16);
  right: var(--space-16);
  max-width: var(--width-trap-promo);
  margin: 0 auto;
  padding: var(--space-18);
  display: flex;
  align-items: flex-start;
  gap: var(--space-12);
}
.trap-promo > div { display: grid; gap: var(--space-8); }
.promo-link {
  justify-self: start;
  background: none;
  border: 0;
  padding: 0;
  font: 600 var(--font-16)/var(--leading-140) var(--sans);
  color: var(--accent);
  text-decoration: underline;
  cursor: pointer;
}

.trap-notice {
  top: var(--trap-top);
  right: var(--space-16);
  width: min(var(--width-trap-notice), var(--screen-width-fit));
  padding: var(--space-18);
  display: grid;
  gap: var(--space-12);
}
.notice-head { display: flex; align-items: flex-start; gap: var(--space-8); }

.trap-form {
  right: var(--space-16);
  bottom: var(--space-16);
  width: min(var(--width-trap-form), var(--screen-width-fit));
  max-height: var(--screen-height-fit);
  overflow-y: auto;
  padding: var(--space-18);
  display: grid;
  gap: var(--space-12);
}
.survey-question { font-weight: 600; }
.survey-answers { --layout-gap: var(--space-8); }
.survey-answer {
  font: 600 var(--font-16)/var(--leading-140) var(--sans);
  color: var(--text);
  background: var(--bg);
  border: var(--border-1) solid var(--line-strong);
  border-radius: var(--radius-8);
  padding: var(--space-10) var(--space-12);
  text-align: left;
  cursor: pointer;
}

.trap-qr {
  left: var(--space-16);
  bottom: var(--space-16);
  width: min(var(--width-trap-qr), var(--screen-width-fit));
  padding: var(--space-18);
  display: grid;
  gap: var(--space-10);
  justify-items: center;
  text-align: center;
}
.trap-qr .trap-close { position: absolute; top: var(--space-8); right: var(--space-8); }
.qr-button {
  display: grid;
  gap: var(--space-8);
  justify-items: center;
  background: none;
  border: 0;
  font: 600 var(--font-14)/var(--leading-140) var(--sans);
  cursor: pointer;
}
.qr {
  width: var(--size-qr);
  height: var(--size-qr);
  padding: var(--space-12);
  background: var(--qr-paper);
  border-radius: var(--radius-8);
  image-rendering: pixelated;
}
.qr-caption { font: 600 var(--font-14)/var(--leading-140) var(--sans); color: var(--muted); }

.trap-chat {
  right: var(--space-16);
  bottom: var(--space-16);
  width: min(var(--width-trap-chat), var(--screen-width-fit));
  padding: var(--space-16);
  display: grid;
  gap: var(--space-12);
}
.trap-chat-head { display: flex; align-items: center; gap: var(--space-10); }
.trap-chat-avatar {
  display: grid;
  place-items: center;
  width: var(--size-trap-avatar);
  height: var(--size-trap-avatar);
  border-radius: 50%;
  background: var(--chat-avatar);
  color: var(--on-chat-avatar);
  font: 700 var(--font-14)/var(--leading-100) var(--sans);
}
.trap-chat-name { font-weight: 600; }
.trap-chat-status { font-size: var(--font-13); color: var(--success); }
.trap-chat-messages { display: grid; gap: var(--space-8); min-height: var(--min-height-trap-messages); }
.trap-chat-bubble {
  justify-self: start;
  max-width: 90%;
  border-radius: var(--radius) var(--radius) var(--radius) var(--radius-4);
  padding: var(--space-10) var(--space-12);
}
.trap-chat-input { display: flex; gap: var(--space-8); }
.trap-chat-input input { flex: 1; min-width: 0; }

/* --- Dialogs: the sign-in trap, result cards and settings --- */

.trap-login, .result, .settings {
  display: grid;
  width: min(var(--dialog-width), var(--screen-width-fit));
  max-height: var(--screen-height-fit);
  padding: var(--space-24);
  background: var(--surface);
  color: var(--text);
  border: var(--border-1) solid var(--line);
  border-radius: var(--dialog-radius);
}
.trap-login { gap: var(--space-14); }
.trap-login h2, .result h2 { font: 700 var(--font-20)/var(--leading-130) var(--sans); }
.login-head { display: flex; align-items: center; }
.login-form { display: grid; gap: var(--space-14); }
.login-form label { display: grid; gap: var(--space-6); font-weight: 600; }
.login-form input, .trap-chat-input input {
  font: var(--font-16)/var(--leading-140) var(--sans);
  color: var(--text);
  background: var(--bg);
  border: var(--border-1) solid var(--line-strong);
  border-radius: var(--radius-8);
  padding: var(--space-10) var(--space-12);
}

.result-trick {
  justify-self: start;
  padding: var(--space-6) var(--space-10);
  border: var(--border-2) solid var(--jack);
  color: var(--jack);
  font: var(--font-tag);
}
.flags { margin: 0; padding-left: var(--space-20); display: grid; gap: var(--space-6); }
.result > .btn { justify-self: start; }

.settings { width: min(var(--width-settings), var(--screen-width-fit)); }
.settings form { justify-self: start; }
.setting {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-8) var(--space-16);
  min-height: var(--target-min);
  font-weight: 600;
}
.setting input {
  appearance: none;
  position: relative;
  width: var(--switch-width);
  height: var(--switch-height);
  margin: 0;
  border: var(--border-1) solid var(--line-strong);
  border-radius: calc(var(--switch-height) / 2);
  background: var(--bg);
  cursor: pointer;
}
.setting input::after {
  content: "";
  position: absolute;
  top: var(--space-3);
  left: var(--space-3);
  width: var(--switch-knob);
  height: var(--switch-knob);
  border-radius: 50%;
  background: var(--muted);
}
/* A switch that shows its state beside its label: the text of the state it has now. */
.setting-state { justify-content: flex-start; }
.setting-state > :first-child { margin-right: auto; }
.setting-state:has(input:checked) .state-off, .setting-state:not(:has(input:checked)) .state-on { display: none; }
.setting input:checked { background: var(--accent); border-color: var(--accent); }
.setting input:checked::after { transform: translateX(var(--switch-travel)); }
.segmented {
  display: flex;
  border: var(--border-1) solid var(--line);
  border-radius: var(--radius-8);
  overflow: hidden;
}
.segmented > * {
  padding: var(--space-4) var(--space-10);
  min-height: var(--target-min);
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-decoration: none;
  cursor: pointer;
}
.segmented > * + * { border-left: var(--border-1) solid var(--line); }
.segmented :is([aria-pressed="true"], [aria-current]) { background: var(--accent); color: var(--on-accent); }

/* --- Phone --- */

/* home.css and site.css size the homepage and the headings for phones, below the values for wide
   screens. */
@media (width <= 760px) {
  .section { padding-block: var(--section-pad-phone); }
}

/* On a phone the links show below the header while the menu button is pressed, which needs a script. */
@media (width <= 760px) and (scripting: enabled) {
  .site-header .menu-button { display: grid; order: 1; }
  .nav-links {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    flex-direction: column;
    gap: 0;
    padding: var(--space-4) var(--page-gutter) var(--space-12);
    background: var(--bg);
    border-bottom: var(--border-1) solid var(--line);
  }
  .nav-links a { padding: var(--space-12) 0; }
  .menu-button[aria-expanded="true"] ~ .nav-links { display: flex; }
}

/* Without a script the gear and the menu button do nothing. The links stay in the header, and the
   links to the languages show in the footer, since the settings are out of reach. */
@media (scripting: none) {
  .nav { flex-wrap: wrap; }
  .settings-button { display: none; }
  .footer-languages { display: flex; gap: var(--space-20); }
}

/* The switch for motion in the settings sets data-motion to "reduce", which stops every animation and
   transition, as the setting of the system does. */
:root[data-motion="reduce"] { scroll-behavior: auto; }

/* A focus moved by the keyboard scrolls at once. A smooth scroll that is still running when the focus
   moves on can leave the next control under the sticky header. */
:root:has(:focus-visible) { scroll-behavior: auto; }
:root[data-motion="reduce"] *,
:root[data-motion="reduce"] ::before,
:root[data-motion="reduce"] ::after { animation: none !important; transition: none !important; }

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
  .nav { transition: box-shadow var(--duration-300); }
  .trap { animation: slide-up var(--duration-350) var(--ease-out) both; }
  .trap-chat-bubble { animation: slide-up var(--duration-250) var(--ease-out) both; }
  .setting input::after { transition: transform var(--duration-150); }
}
