/* ==========================================================================
 * TokiCam landing page
 *
 * PALETTE PROVENANCE — read before changing any colour.
 *
 * The house rule (station/docs/design-philosophy.md, "One palette source, no
 * drift") is: every retro colour resolves from
 *     station/packages/effects/src/win98-tokens.ts
 * and a hex is NEVER re-hardcoded in a component or stylesheet.
 *
 * This file breaks that rule, deliberately and visibly. This site is a
 * standalone no-build folder in a different repo; it cannot import the tokens
 * module, and adding a bundler for one page is not worth the failure mode.
 * So the values below are COPIED VERBATIM from win98-tokens.ts and this
 * comment is the mirror-tracking note the rule asks for.
 *
 * >>> If win98-tokens.ts changes, mirror the change here. <<<
 *
 * The bevel recipes (.w98-raised / .w98-sunken / .win98-btn / focus cue) are
 * likewise copied verbatim from station/apps/station/src/index.css. Do not
 * "improve" them — the stacked inset-shadow order is what sells the Win98
 * object, and it is already correct.
 * ========================================================================== */

:root {
  /* --- Win98 system palette (mirror of win98-tokens.ts) --- */
  --w98-face: #c0c0c0; /* WIN98_GREY / ButtonFace */
  --w98-light: #ffffff; /* WIN98_BEVEL_LIGHT / ButtonHighlight */
  --w98-light-inner: #dfdfdf; /* WIN98_BEVEL_LIGHT_INNER / 3DLight */
  --w98-dark: #808080; /* WIN98_BEVEL_DARK / ButtonShadow */
  --w98-darker: #000000; /* WIN98_BEVEL_DARKER / 3DDarkShadow */
  --w98-desktop: #008080; /* WIN98_DESKTOP_TEAL */
  --w98-title: #000080; /* WIN98_TITLE_BLUE */
  --w98-title-light: #1084d0; /* WIN98_TITLE_BLUE_LIGHT */
  --w98-text-white: #ffffff;
  --w98-lcd-green: #00ff41; /* WIN98_LCD_GREEN — phosphor readouts */

  /* --- Fonts (mirror of WIN98_FONT_FAMILY / WIN98_DOS_FONT_FAMILY) ---
   * No webfonts. The kiosk constraint that produced this stack does not apply
   * to a web page, but staying on system faces keeps the page under 20KB and
   * keeps the two surfaces looking like one product. */
  --font-ui: 'MS UI Gothic', 'MS Sans Serif', 'Microsoft Sans Serif', sans-serif;
  --font-dos: 'Lucida Console', 'MS Gothic', Consolas, monospace;

  /* --- Motion: the house curve (design-philosophy.md) --- */
  --dur-structural: 180ms;
  --dur-micro: 120ms;
  --ease: ease-out;

  --taskbar-h: 40px;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

body {
  margin: 0;
  /* 16px floor. The admin portal's compact-type scale deliberately never
   * overrides --text-base for this reason (iOS input zoom); same discipline. */
  font: 16px/1.5 var(--font-ui);
  color: var(--w98-darker);
  background: var(--w98-desktop);
  overflow-x: hidden;
}

/* ==========================================================================
 * Bevel recipes — verbatim from station/apps/station/src/index.css
 * ========================================================================== */

.w98-raised {
  background: var(--w98-face);
  box-shadow:
    inset -1px -1px 0 var(--w98-darker),
    inset 1px 1px 0 var(--w98-light),
    inset -2px -2px 0 var(--w98-dark),
    inset 2px 2px 0 var(--w98-light-inner);
}

.w98-sunken {
  box-shadow:
    inset -1px -1px 0 var(--w98-light),
    inset 1px 1px 0 var(--w98-dark),
    inset -2px -2px 0 var(--w98-light-inner),
    inset 2px 2px 0 var(--w98-darker);
}

.w98-sunken-1 {
  box-shadow:
    inset -1px -1px 0 var(--w98-light),
    inset 1px 1px 0 var(--w98-dark);
}

.win98-btn {
  background: var(--w98-face);
  color: var(--w98-darker);
  box-shadow:
    inset -1px -1px 0 var(--w98-darker),
    inset 1px 1px 0 var(--w98-light),
    inset -2px -2px 0 var(--w98-dark),
    inset 2px 2px 0 var(--w98-light-inner);
}

.win98-btn:active:not(:disabled),
.win98-btn.is-pressed {
  box-shadow:
    inset -1px -1px 0 var(--w98-light),
    inset 1px 1px 0 var(--w98-darker),
    inset -2px -2px 0 var(--w98-light-inner),
    inset 2px 2px 0 var(--w98-dark);
}

/* The authentic keyboard-focus cue: a black dotted rectangle just inside the
 * control. Not a modern glow — the correct retro detail is also the accessible
 * one here. */
.win98-btn:focus-visible,
.win98-focus:focus-visible,
a:focus-visible {
  outline: 1px dotted var(--w98-darker);
  outline-offset: -4px;
}

/* ==========================================================================
 * Parallax scene
 * ========================================================================== */

.scene {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}

/* --px / --py are written by app.js (normalised -1..1); --depth scales how far
 * each layer travels. One transform per layer, driven by one rAF loop. */
.layer {
  position: absolute;
  inset: 0;
  --px: 0;
  --py: 0;
  transform: translate3d(calc(var(--px) * 1px), calc(var(--py) * 1px), 0);
  will-change: transform;
}

.motif {
  position: absolute;
  opacity: 0.5;
  filter: drop-shadow(2px 2px 0 rgba(0, 0, 0, 0.35));
}

.motif--cassette {
  top: 14%;
  left: 6%;
  transform: rotate(-9deg);
}
.motif--canister {
  bottom: 18%;
  right: 9%;
  transform: rotate(7deg);
}
.motif--crt {
  bottom: 12%;
  left: 8%;
  transform: rotate(4deg);
}
.motif--filmstrip {
  top: 8%;
  right: 7%;
  transform: rotate(11deg);
}

.motif--kana {
  font-family: var(--font-ui);
  font-size: 2rem;
  font-weight: 700;
  letter-spacing: 0.18em;
  color: var(--w98-text-white);
  opacity: 0.22;
  top: 30%;
  right: 16%;
  writing-mode: vertical-rl;
  filter: none;
}
.motif--kana-2 {
  top: auto;
  bottom: 24%;
  right: auto;
  left: 20%;
  font-size: 1.5rem;
}

.motif--star {
  top: 62%;
  right: 26%;
  opacity: 0.65;
}

/* CRT scanlines + film grain: pure CSS, no image requests. */
.crt {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: repeating-linear-gradient(
    to bottom,
    rgba(0, 0, 0, 0.13) 0px,
    rgba(0, 0, 0, 0.13) 1px,
    transparent 1px,
    transparent 3px
  );
  mix-blend-mode: multiply;
}

.grain {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  opacity: 0.16;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E");
}

/* ==========================================================================
 * Window
 * ========================================================================== */

.desktop {
  position: relative;
  z-index: 2;
  min-height: 100%;
  display: grid;
  place-items: center;
  padding: 24px 16px calc(var(--taskbar-h) + 32px);
}

.window {
  width: 100%;
  max-width: 720px;
  padding: 3px;
  animation: window-in var(--dur-structural) var(--ease) both;
}

@keyframes window-in {
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

.titlebar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 3px 3px 3px 4px;
  background: linear-gradient(90deg, var(--w98-title), var(--w98-title-light));
  color: var(--w98-text-white);
}

.titlebar__icon {
  display: grid;
  place-items: center;
  width: 18px;
  height: 18px;
  background: var(--w98-text-white);
  color: var(--w98-title);
  font-size: 13px;
  font-weight: 700;
}

.titlebar__text {
  flex: 1;
  margin: 0;
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.titlebar__buttons {
  display: flex;
  gap: 2px;
}

.tbtn {
  display: grid;
  place-items: center;
  width: 20px;
  height: 18px;
  background: var(--w98-face);
  color: var(--w98-darker);
  font-size: 11px;
  line-height: 1;
  box-shadow:
    inset -1px -1px 0 var(--w98-darker),
    inset 1px 1px 0 var(--w98-light),
    inset -2px -2px 0 var(--w98-dark),
    inset 2px 2px 0 var(--w98-light-inner);
}

.window__body {
  padding: 32px 28px 28px;
  text-align: center;
}

/* --- Wordmark: romaji + kana lockup, 時 as the square icon accent --- */

.wordmark {
  /* One source for the lockup metrics. The 時 square is sized *from* these, so
   * it stays exactly as tall as the romaji + kana stack at every viewport
   * width — change a type size here and the icon follows on its own. Both rows
   * share --lockup-leading, so the stack is (romaji + kana) * leading tall. */
  --lockup-romaji: clamp(2rem, 9vw, 3rem);
  --lockup-kana: clamp(0.8125rem, 3.2vw, 1rem);
  --lockup-leading: 1.05;
  --lockup-h: calc((var(--lockup-romaji) + var(--lockup-kana)) * var(--lockup-leading));

  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
}

.wordmark__icon {
  display: grid;
  place-items: center;
  width: var(--lockup-h);
  height: var(--lockup-h);
  flex: none;
  background: var(--w98-title);
  color: var(--w98-text-white);
  /* ~0.56 of the box keeps the glyph's optical weight where it was at 56px. */
  font-size: calc(var(--lockup-h) * 0.56);
  font-weight: 700;
  line-height: 1;
  box-shadow:
    inset -1px -1px 0 var(--w98-darker),
    inset 1px 1px 0 var(--w98-title-light);
}

.wordmark__type {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  line-height: var(--lockup-leading);
}

.wordmark__romaji {
  font-size: var(--lockup-romaji);
  font-weight: 700;
  letter-spacing: 0.06em;
}

.wordmark__kana {
  font-size: var(--lockup-kana);
  letter-spacing: 0.42em;
  color: #3a3a3a;
  padding-left: 0.2em;
}

/* --- Tagline --- */

.tagline {
  margin: 22px 0 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.tagline__beats {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0 8px;
  font-size: clamp(1rem, 4vw, 1.25rem);
  font-weight: 700;
  letter-spacing: 0.04em;
}

.tagline__beats b {
  color: var(--w98-title);
}

.tagline__what {
  font-size: clamp(0.9375rem, 3.6vw, 1.125rem);
  color: #2a2a2a;
}

/* --- Status well: the phosphor readout --- */

.status {
  margin: 24px auto 0;
  padding: 14px 16px;
  background: var(--w98-darker);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 12px;
}

.status__line {
  margin: 0;
  font-family: var(--font-dos);
  font-size: clamp(0.875rem, 3.4vw, 1.0625rem);
  color: var(--w98-lcd-green);
  text-shadow: 0 0 6px rgba(0, 255, 65, 0.5);
  letter-spacing: 0.04em;
}

.status__caret {
  margin-right: 6px;
}

.status__cursor {
  animation: blink 1.06s step-end infinite;
}

@keyframes blink {
  50% {
    opacity: 0;
  }
}

.tilt-toggle {
  font-family: var(--font-ui);
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  /* Touch target sized for fingers, per the house rule that the look bends to
   * the feel where they conflict. */
  min-height: 34px;
  padding: 0 14px;
  border: 0;
  cursor: pointer;
}

/* --- Contact --- */

.contact {
  margin: 22px 0 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 0.9375rem;
}

.contact a {
  color: var(--w98-title);
  font-weight: 700;
  text-underline-offset: 3px;
}

.contact__soon {
  color: #4a4a4a;
  font-size: 0.875rem;
}

/* --- Footer: the entity line HitPay verification looks for --- */

.window__footer {
  margin: 0 3px 3px;
  padding: 10px 14px;
  background: var(--w98-face);
  box-shadow:
    inset -1px -1px 0 var(--w98-light),
    inset 1px 1px 0 var(--w98-dark);
}

.window__footer p {
  margin: 0;
  font-size: 0.8125rem;
  text-align: center;
  color: #2a2a2a;
}

/* Break the entity line at the middot separators, never inside a segment —
 * "UEN 202634703E" split across two lines is unreadable to a verification
 * reviewer, which is the one audience this line exists for. */
.window__footer .nobr {
  white-space: nowrap;
}

/* ==========================================================================
 * Taskbar
 * ========================================================================== */

.taskbar {
  position: fixed;
  z-index: 3;
  left: 0;
  right: 0;
  bottom: 0;
  height: var(--taskbar-h);
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 6px;
  background: var(--w98-face);
  box-shadow: inset 0 1px 0 var(--w98-light);
  /* Keep clear of the iOS home indicator. */
  padding-bottom: max(4px, env(safe-area-inset-bottom));
  height: calc(var(--taskbar-h) + env(safe-area-inset-bottom));
}

.taskbar__start {
  display: flex;
  align-items: center;
  gap: 5px;
  height: 28px;
  padding: 0 10px;
  font-size: 0.8125rem;
  font-weight: 700;
}

.taskbar__flag {
  width: 14px;
  height: 14px;
  background:
    linear-gradient(135deg, #ff5f8f 50%, transparent 50%) top left / 7px 7px no-repeat,
    linear-gradient(135deg, #7fd4ff 50%, transparent 50%) top right / 7px 7px no-repeat,
    linear-gradient(135deg, #ffcf3f 50%, transparent 50%) bottom left / 7px 7px no-repeat,
    linear-gradient(135deg, #00c07a 50%, transparent 50%) bottom right / 7px 7px no-repeat;
}

.taskbar__task {
  flex: 1;
  min-width: 0;
  height: 28px;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 10px;
  font-size: 0.8125rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.taskbar__tray {
  height: 28px;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 10px;
  font-size: 0.8125rem;
  font-variant-numeric: tabular-nums;
}

.taskbar__tz {
  color: #3a3a3a;
  font-size: 0.6875rem;
}

/* ==========================================================================
 * Responsive
 * ========================================================================== */

@media (max-width: 767px) {
  .window {
    max-width: 92vw;
  }

  .window__body {
    padding: 24px 18px 22px;
  }

  .wordmark {
    gap: 10px;
  }

  /* No icon size override here any more — --lockup-h is viewport-relative, so
   * the square tracks the type down to 320px on its own. */

  /* The big motifs crowd a phone and make the parallax feel jittery rather
   * than atmospheric. Keep the two smallest and the kana. */
  .motif--filmstrip,
  .motif--crt {
    display: none;
  }

  .motif--cassette {
    left: -4%;
    top: 8%;
  }

  .taskbar__task {
    display: none;
  }
}

@media (max-width: 359px) {
  .wordmark {
    flex-direction: column;
  }

  .wordmark__type {
    align-items: center;
  }
}

/* ==========================================================================
 * Reduced motion — non-negotiable, matching station/apps/station/src/index.css.
 * app.js additionally refuses to start the rAF loop under this query, so the
 * parallax is genuinely not running, not merely visually still.
 * ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  .layer {
    transform: none !important;
  }

  .status__cursor {
    animation: none;
    opacity: 1;
  }
}
