/* kan.fyi — coming-soon page styles.
   Ported from the design system project's `Coming soon.dc.html`. That file is a
   Claude Design mock: every rule lives in a `style="..."` attribute because the
   mock runtime has no stylesheet step, and hover/active states ride on custom
   `style-hover` / `style-active` attributes it interprets itself. Neither
   survives outside that runtime, so the rules are lifted into classes here.
   Values are carried over verbatim; where a number looks odd (11.5px, 14.5px)
   it is the design's, not a typo. */

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

/* The HTML `hidden` attribute hides an element only through the UA stylesheet's
   `[hidden] { display: none }`, which sits BELOW author rules in the cascade —
   so any author `display:` declaration silently defeats it. app.js toggles
   `.hidden` on seven elements that each set `display: inline-flex` or `flex`
   (the deploy chip, the live pill, both site-card badges, the form, and the
   success and error messages), and every one of them stayed on screen: the page
   showed "uploading… 20%" next to a live URL, "Reserved for you" next to "Live",
   and "You're on the list" before anyone had typed anything.

   `!important` is load-bearing here, not a shortcut — it is what restores the
   precedence the UA rule was supposed to have. Do not remove it without also
   removing every `display:` on the elements listed above. Only the terminal's
   plain <div> lines, which set no display, ever hid correctly. */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--amber-400);
}

::placeholder { color: var(--ink-400); }

/* Visible focus for keyboard users. The design shows no focus treatment at all
   — an omission, not a decision: this page's only controls are the email input
   and its submit button, and both must be reachable without a mouse. Ring
   geometry and color come from the design system's own tokens. */
:focus-visible {
  outline: var(--ring-width) solid var(--ink-900);
  outline-offset: var(--ring-gap);
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ── Shell ──────────────────────────────────────────────────────────────── */

.page {
  position: relative;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--amber-400);
  color: var(--ink-900);
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.55;
  overflow: hidden;
}

.header {
  position: relative;
  z-index: 2;
  display: flex;
  justify-content: center;
  padding: 28px 24px 0;
}

/* The design pulls the wordmark in as <img src="ds/assets/kan-logo.svg">. It is
   inlined in the markup instead: that SVG sets its lettering in Plus Jakarta
   Sans via an SVG <text> element, and an SVG loaded through <img> renders in an
   isolated document that cannot reach the parent page's webfonts — the wordmark
   would silently fall back to a system sans on every browser. Inline, it
   inherits the loaded font like any other text. */
.logo {
  height: 30px;
  display: block;
}

.main {
  position: relative;
  z-index: 2;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 26px;
  text-align: center;
  padding: 48px 24px 56px;
  max-width: 680px;
  margin: 0 auto;
  width: 100%;
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 7px 16px;
  border-radius: 999px;
  background: var(--ink-900);
  color: var(--paper-100);
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.02em;
}

.eyebrow-dot {
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: var(--amber-400);
  animation: kanPulse 2s ease-in-out infinite;
}

.headline {
  margin: 0;
  font-size: clamp(48px, 8vw, 84px);
  line-height: 1;
  letter-spacing: -0.025em;
  font-weight: 800;
  color: var(--ink-900);
}

.subhead {
  margin: 0;
  max-width: 440px;
  font-size: 17px;
  line-height: 1.6;
  color: var(--ink-800);
  text-wrap: pretty;
}

/* ── Deploy animation (chip → progress bar → live pill) ─────────────────── */

.deploy {
  position: relative;
  width: min(400px, 100%);
  display: flex;
  flex-direction: column;
  gap: 9px;
  padding-top: 36px;
}

/* kanDrop carries the -50% X translation, so this only needs the left anchor. */
.deploy-chip {
  position: absolute;
  top: 0;
  left: 50%;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 8px;
  background: var(--card);
  box-shadow: var(--shadow-md);
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--ink-800);
  white-space: nowrap;
  animation: kanDrop 0.9s var(--ease-spring) both;
}

.deploy-chip-mark {
  color: var(--amber-600);
  font-weight: 700;
}

.deploy-track {
  height: 38px;
  display: flex;
  align-items: center;
}

.deploy-bar {
  width: 100%;
  height: 10px;
  border-radius: 999px;
  background: color-mix(in oklab, var(--ink-900) 12%, transparent);
  overflow: hidden;
}

.deploy-bar-fill {
  height: 100%;
  width: 0%;
  border-radius: 999px;
  background: var(--ink-900);
  transition: width 90ms linear;
}

.deploy-live {
  margin: 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px 18px;
  border-radius: 999px;
  background: var(--card);
  box-shadow: var(--shadow-lg);
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--green-800);
  animation: kanPop 0.35s var(--ease-spring) both;
}

.deploy-live-dot {
  width: 7px;
  height: 7px;
  border-radius: 999px;
  background: var(--green-600);
  animation: kanPulse 2s ease-in-out infinite;
}

.deploy-status {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--ink-800);
  align-self: flex-end;
  min-height: 18px;
}

/* ── Waitlist form ──────────────────────────────────────────────────────── */

.notify {
  display: flex;
  gap: 8px;
  width: min(440px, 100%);
  background: var(--card);
  border-radius: 999px;
  padding: 6px;
  box-shadow: var(--shadow-lg);
}

.notify-input {
  flex: 1;
  min-width: 0;
  border: none;
  outline: none;
  background: transparent;
  padding: 0 16px;
  font-family: var(--font-sans);
  font-size: 15px;
  color: var(--ink-900);
}

/* The input sits inside a pill that reads as one control, so the focus ring
   goes on the whole form rather than the bare input (which has no border of
   its own to ring). */
.notify:focus-within {
  outline: var(--ring-width) solid var(--ink-900);
  outline-offset: var(--ring-gap);
}

.notify-input:focus-visible { outline: none; }

.notify-button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 46px;
  padding: 0 22px;
  border-radius: 999px;
  border: 1px solid transparent;
  background: var(--ink-900);
  color: var(--paper-50);
  font-family: var(--font-sans);
  font-size: 14.5px;
  font-weight: 700;
  white-space: nowrap;
  cursor: pointer;
  text-decoration: none; /* 404.html reuses this class on an <a> */
  transition:
    background var(--duration-fast) var(--ease-standard),
    transform var(--duration-instant) var(--ease-spring);
}

.notify-button:hover { background: var(--ink-800); }
.notify-button:active { transform: translateY(1px); }

.notify-button[disabled] {
  cursor: default;
  opacity: 0.65;
}

.notify-done {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 13px 22px;
  border-radius: 999px;
  background: var(--success-subtle);
  color: var(--success-subtle-foreground);
  font-size: 14.5px;
  font-weight: 700;
  box-shadow: var(--shadow-md);
}

/* Not in the design — the mock's submit handler cannot fail, so it never had to
   show anything going wrong. A form wired to a real endpoint can fail (offline,
   rate-limited, malformed address), and silently swallowing that would leave
   someone believing they had signed up. Uses the design system's destructive
   pair rather than inventing a color. */
.notify-error {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 18px;
  border-radius: 999px;
  background: var(--destructive-subtle);
  color: var(--destructive-subtle-foreground);
  font-size: 13.5px;
  font-weight: 600;
}

/* ── Footer ─────────────────────────────────────────────────────────────── */

.footer {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  flex-wrap: wrap;
  padding: 0 24px 28px;
  font-size: 12.5px;
  color: var(--ink-800);
}

.footer-mark { font-weight: 600; }

.footer-sep {
  width: 4px;
  height: 4px;
  border-radius: 999px;
  background: var(--ink-900);
  opacity: 0.35;
}

.footer-mcp {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-mono);
  font-size: 12px;
  background: color-mix(in oklab, var(--ink-900) 8%, transparent);
  border-radius: 999px;
  padding: 5px 12px;
}

/* ── Decorative floating cards ──────────────────────────────────────────── */

.floaters {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.card-site {
  --tilt: -3deg;
  position: absolute;
  top: 12%;
  left: max(3vw, 16px);
  width: 230px;
  background: var(--card);
  border-radius: 18px;
  box-shadow: var(--shadow-lg);
  padding: 14px;
  transform: rotate(-3deg);
  animation: kanFloat 8s ease-in-out infinite;
}

.card-site-url {
  display: flex;
  align-items: center;
  gap: 7px;
  background: var(--paper-100);
  border-radius: 999px;
  padding: 6px 11px;
}

.card-site-dot {
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: var(--amber-500);
  flex: none;
  animation: kanPulse 2s ease-in-out infinite;
}

.card-site-host {
  font-family: var(--font-mono);
  font-size: 11.5px;
  color: var(--ink-800);
}

.card-site-skeleton {
  margin-top: 12px;
  display: flex;
  flex-direction: column;
  gap: 7px;
}

.card-site-skeleton > span {
  height: 11px;
  border-radius: 5px;
  transition: background 500ms ease;
  background: var(--paper-100);
}

.card-site-skeleton > span:nth-child(1) { width: 64%; background: var(--paper-200); }
.card-site-skeleton > span:nth-child(2) { width: 86%; }
.card-site-skeleton > span:nth-child(3) { width: 52%; }

/* "live" recolors the stack so the top row picks up brand amber — the moment
   the placeholder stops being a placeholder. */
.card-site[data-live="true"] .card-site-skeleton > span:nth-child(1) { background: var(--amber-200); }
.card-site[data-live="true"] .card-site-skeleton > span:nth-child(2),
.card-site[data-live="true"] .card-site-skeleton > span:nth-child(3) { background: var(--paper-300); }

.card-site-badges { margin-top: 12px; display: flex; }

.card-site-reserved {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--paper-100);
  color: var(--ink-600);
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
}

.card-site-livebadge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
  border-radius: 999px;
  background: var(--green-100);
  color: var(--green-800);
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
  animation: kanPop 0.3s var(--ease-spring) both;
}

.card-site-livebadge-dot {
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: var(--green-600);
  flex: none;
}

.card-term {
  --tilt: 3deg;
  position: absolute;
  bottom: 14%;
  right: max(3vw, 16px);
  width: 272px;
  background: var(--ink-900);
  border-radius: 16px;
  box-shadow: var(--shadow-xl);
  padding: 14px 16px;
  transform: rotate(3deg);
  animation: kanFloat 9s ease-in-out infinite 0.7s;
  font-family: var(--font-mono);
  font-size: 12px;
  line-height: 1.75;
  color: var(--paper-100);
}

.card-term-chrome {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 8px;
}

/* Scoped to an explicit class rather than `.card-term-chrome > span`. The
   mcp.kan.fyi label is also a direct span child of the chrome row, and that
   descendant selector (specificity 0,1,1) outranks `.card-term-host` (0,1,0) —
   so the label silently inherited the dot's 8px square box and `flex: none`,
   and its text spilled 62px out past the card's right edge. In the design each
   dot carried its own inline styles, so there was no shared selector to leak
   from; the leak was introduced by lifting those styles into classes. */
.card-term-dot {
  width: 8px;
  height: 8px;
  border-radius: 999px;
  flex: none;
}

.card-term-dot:nth-child(1) { background: var(--red-500); }
.card-term-dot:nth-child(2) { background: var(--amber-500); }
.card-term-dot:nth-child(3) { background: var(--green-500); }

.card-term-host {
  margin-left: auto;
  font-size: 10px;
  letter-spacing: 0.04em;
  color: color-mix(in oklab, var(--paper-100) 55%, transparent);
}

/* Fixed height keeps the card from resizing as lines appear — the design's
   min-height, made exact so the floating card never jitters mid-animation. */
.card-term-body { min-height: 64px; }

.card-term-prompt { color: var(--green-300); }

.card-term-cursor { animation: kanBlink 1s step-end infinite; }

.card-term-progress { color: color-mix(in oklab, var(--paper-100) 65%, transparent); }

.card-term-done { color: var(--green-300); }

/* ── Keyframes ──────────────────────────────────────────────────────────── */

@keyframes kanFloat {
  0%, 100% { transform: translateY(0) rotate(var(--tilt, 0deg)); }
  50%      { transform: translateY(-8px) rotate(var(--tilt, 0deg)); }
}

@keyframes kanPulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.35; }
}

@keyframes kanDrop {
  0%   { transform: translate(-50%, -34px) scale(0.9); opacity: 0; }
  65%  { transform: translate(-50%, 3px) scale(1); opacity: 1; }
  100% { transform: translate(-50%, 0) scale(1); opacity: 1; }
}

@keyframes kanPop {
  0%   { transform: scale(0.8); opacity: 0; }
  100% { transform: scale(1); opacity: 1; }
}

@keyframes kanBlink {
  0%, 49%   { opacity: 1; }
  50%, 100% { opacity: 0; }
}

/* The floating cards are ornament, and below this width they would collide with
   the headline. The design drops them outright rather than shrinking them. */
@media (max-width: 860px) {
  .floaters { display: none; }
}
