/* Cipher Shinobi front door (Fuda AK-1136), ported from the locked design /d/ (cs-frontdoor-proto
   df1f83f): the ruled default, the stacked mid mark. Tokens are the CS design system V2 "Refined
   Terminal" values. Dark only, square corners, Blaze as the single accent, nothing heavier than
   weight 400. The faint phosphor bloom, the cursor glow and the vignette are Kage-directed
   departures from the DS "no glow, no gradient" rule, held low so the text stays crisp.
   Asset URLs below are rewritten to content-hashed /s/ paths by scripts/render.mjs. */

@font-face {
  font-family: "CS Plex";
  src: url("/s/IBMPlexMono-Regular-Latin1.e8993d9466.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: block;
}
@font-face {
  font-family: "CS Plex";
  src: url("/s/IBMPlexMono-Light-Latin1.ec38551173.woff2") format("woff2");
  font-weight: 300;
  font-style: normal;
  font-display: block;
}

:root {
  color-scheme: dark;
  --void: #000000;
  --white: #ffffff;
  --light: #e0e0e0;
  --silver: #cccccc;
  --ash: #94979c;
  --smoke: #85888e;
  --blaze: #fa5d19;
  --line-quiet: #1f2228;
  --line: #373a41;
  --line-em: #61656c;
  --mono: "CS Plex", "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --ease: cubic-bezier(0.2, 0, 0.2, 1);
  --gutter: 16px;
  --text: 16px; /* 16px on phones: iOS Safari zooms any smaller input */
  --lead: 1.65;

  --term: "CS Plex", "IBM Plex Mono", ui-monospace, "SF Mono", Menlo, monospace;
  --phos: #e4e6e1;       /* P4 white phosphor */
  --dim: #8b908a;
  --faint: #5a5e59;      /* rules and decoration only (dashes, key-cap borders, underlines) */
  --faint-text: #777b76; /* faint TEXT: 4.88:1 on black, WCAG AA (Kage ruling 22 Oct, contrast) */
  --fs: 13px;
  --lh: 1.42;
  --row: calc(var(--fs) * var(--lh));
  --k: 0.8125;           /* phones: 16px inputs (no iOS zoom) drawn at 13px */
  --in: 16px;
  --hit: 46px;           /* input line height: a 44px+ target after scaling */
  --glow: 0 0 1px rgba(228, 230, 225, 0.3), 0 0 7px rgba(228, 230, 225, 0.07);
  --hot: 0 0 6px rgba(250, 93, 25, 0.55), 0 0 14px rgba(250, 93, 25, 0.25);
}

@media (min-width: 900px) {
  :root { --gutter: 48px; --text: 15px; --fs: 14px; --k: 1; --in: 14px; }
}

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

html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; background: var(--void); }

body {
  margin: 0;
  min-height: 100svh;
  background: var(--void);
  color: var(--phos);
  font-family: var(--term);
  font-weight: 400;
  font-size: var(--fs);
  line-height: var(--lh);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

p { margin: 0; }

/* Author display rules outrank the UA [hidden] rule; this restores it so JS can hide rows. */
[hidden] { display: none !important; }

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

.link {
  color: var(--silver);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  text-decoration-color: var(--line-em);
  transition: color 120ms var(--ease);
}
.link:hover { color: var(--blaze); text-decoration-color: var(--blaze); }
.link:focus-visible { outline: 1px solid var(--blaze); outline-offset: 3px; }

@keyframes cs-type-on {
  from { clip-path: inset(0 100% 0 0); }
  to { clip-path: inset(0 0 0 0); }
}

.dots { display: block; }

/* ── The tube ──────────────────────────────────────────────────── */

.crt {
  position: relative;
  min-height: 100svh;
  padding:
    calc(28px + env(safe-area-inset-top))
    calc(18px + env(safe-area-inset-right))
    calc(28px + env(safe-area-inset-bottom))
    calc(18px + env(safe-area-inset-left));
  text-shadow: var(--glow);
}
@media (min-width: 900px) {
  .crt { padding: 52px 56px 72px max(56px, 7vw); }
}

.vignette {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 18;
  background: radial-gradient(ellipse 120% 100% at 40% 45%, rgba(0, 0, 0, 0) 58%, rgba(0, 0, 0, 0.45) 100%);
}

/* ── Initiation cascade ────────────────────────────────────────── */

.init {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 100svh;
  overflow: hidden;
  padding: inherit;
  white-space: pre;
  color: var(--dim);
  display: none;
}
.crt.is-init .init { display: block; }
.init .l { min-height: var(--row); }
.init .hi { color: var(--phos); }
.init .ts { color: var(--faint-text); }
.init .ok { color: var(--blaze); text-shadow: var(--hot); }
.init .wait { color: var(--faint-text); }
.init .hex { color: var(--faint-text); }
.init .hex b { font-weight: 400; color: var(--dim); }
.init .asc { color: var(--phos); }
.init .gl { color: var(--phos); }
.init .bar { color: var(--phos); }
.init .cmd { color: var(--phos); }

/* Glyph cells for every scramble: one column wide whatever the glyph. */
.cell {
  display: inline-block;
  width: 1ch;
  overflow: hidden;
  vertical-align: bottom;
  text-align: center;
}
.cell.scr { color: var(--blaze); text-shadow: var(--hot); }

/* While the cascade runs, the session is invisible but still in the
   accessibility tree (opacity, not visibility). */
.js .crt.is-init .door,
.js .crt.is-off .door { opacity: 0; }

/* ── Head: the mark and the decoded name ───────────────────────── */

.door { max-width: 80ch; }

.head {
  display: flex;
  align-items: center;
  gap: 3ch;
  margin: 0 0 calc(var(--row) * 1.2);
}
.head .mark { width: 96px; height: 96px; flex: none; }
@media (min-width: 900px) {
  .head .mark { width: 120px; height: 120px; }
}
/* The ruled layout (Kage 16:33 GST): the mark stacked above CIPHER SHINOBI and the kanji,
   the logo-to-name gap 1.25 terminal lines; door.js sets the mark's exact size from the live
   font metrics (1.584x the name block, the "mid" mark). */
.mark-stacked .head { flex-direction: column; align-items: flex-start; gap: calc(var(--row) * 1.25); }
.mark-stacked .head .mark { width: 76px; height: 76px; }
.mark-stacked.mark-small .head .mark { width: 50px; height: 50px; }
.mark-stacked.mark-mid .head .mark { width: 55px; height: 55px; }
@media (min-width: 900px) {
  .mark-stacked .head .mark { width: 88px; height: 88px; }
  .mark-stacked.mark-small .head .mark { width: 53px; height: 53px; }
  .mark-stacked.mark-mid .head .mark { width: 58px; height: 58px; }
}
.js .head .mark { opacity: 0; }
.js .head.is-on .mark { opacity: 1; }

.name {
  margin: 0;
  font-size: calc(var(--fs) * 1.15);
  line-height: var(--lh);
  font-weight: 400;
  color: var(--phos);
  text-transform: uppercase;
}
.name .cell { width: 1ch; margin-right: 0.42ch; }
.name .gap { display: inline-block; width: 1.4ch; }
.js .name .vis:empty::after { content: "\00a0"; }

.kanji {
  margin: 0.3em 0 0;
  font-family: var(--term);
  font-weight: 400;
  color: var(--dim);
  letter-spacing: 0.62em;
  font-size: var(--fs);
}
.js [data-kanji] { opacity: 0; }
.js [data-kanji].is-on { opacity: 1; }

/* ── Session rule ──────────────────────────────────────────────── */

.rule--session {
  margin: 0 0 calc(var(--row) * 0.7);
  line-height: 1;
  white-space: nowrap;
  overflow: hidden;
  color: var(--faint);
  letter-spacing: 0.08em;
  text-shadow: none;
}
.js .rule--session:not(.is-on) { visibility: hidden; }

/* ── Shell line + typed output ─────────────────────────────────── */

.shell { margin: 0 0 calc(var(--row) * 0.5); color: var(--dim); white-space: pre-wrap; }
.shell .ps { color: var(--faint-text); }
.shell .cmd { color: var(--phos); }
.js .shell:not(.is-on) { visibility: hidden; }

.ln { margin: 0; min-height: var(--row); color: var(--phos); text-wrap: pretty; }
.ln--status { color: var(--dim); font-size: inherit; letter-spacing: 0.06em; font-weight: 400; }
.ln--sys { color: var(--phos); padding-left: 2ch; text-indent: -2ch; }
.ln--quiet { color: var(--faint-text); }
.ln--gap { min-height: 1em !important; } /* the design system's rule outranks the session's 0.6-row gap, as in /d/ */

.js [data-type]:not(.is-ready) { visibility: hidden; }
.js .is-pending > .vis { visibility: hidden; }

.cursor {
  display: inline-block;
  width: 1ch;
  height: 1.15em;
  margin-left: 1px;
  vertical-align: -0.2em;
  background: var(--blaze);
  box-shadow: var(--hot);
}
.cursor.idle { animation: cs-blink 1.06s steps(1) infinite; }
@keyframes cs-blink {
  0%, 49% { opacity: 1; }
  50%, 100% { opacity: 0; }
}

/* ── Prompts ───────────────────────────────────────────────────── */

.prompts { margin: calc(var(--row) * 1) 0 0; }
.js [data-form]:not(.is-live) { display: none; }
.row { margin: 0 0 calc(var(--row) * 0.7); }

.q { display: block; color: var(--phos); font-weight: 400; padding-left: 2ch; text-indent: -2ch; }
.q .chev { color: var(--faint-text); transition: color 120ms var(--ease); }
.row:focus-within .q .chev { color: var(--blaze); }
.row.is-current .q .chev { color: var(--blaze); text-shadow: var(--hot); }

.help, .line, .err, .count, .review dl, .keys--review, .consent { padding-left: 2ch; }
.help { color: var(--faint-text); font-size: inherit; letter-spacing: 0; line-height: 1.55; margin: 0; }
.help .hint-fine { color: var(--faint-text); }

.line { display: flex; flex-wrap: wrap; align-items: center; column-gap: 1.5ch; min-height: var(--hit); }

/* The field keeps at least 60% of the line; when two key-caps do not fit
   beside it (phones), they drop to the next line, flush right. */
.field { position: relative; flex: 1 1 60%; min-width: 0; height: var(--hit); display: block; padding: 0; margin: 0; gap: 0; }
.field--multi { height: auto; min-height: var(--hit); }

.field input,
.field textarea {
  display: block;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--phos);
  font-family: var(--term);
  font-weight: 400;
  font-size: var(--in);
  line-height: var(--lh);
  letter-spacing: 0;
  text-shadow: var(--glow);
  caret-color: transparent;
  outline: none;
  -webkit-appearance: none;
  appearance: none;
  min-width: 0;
  min-height: 44px;
  width: calc(100% / var(--k));
  transform: scale(var(--k));
  transform-origin: 0 0;
}
.field input {
  position: absolute;
  left: 0;
  top: 0;
  height: calc(var(--hit) / var(--k));
}
.field textarea {
  resize: none;
  overflow: hidden;
  padding: calc((var(--hit) / var(--k) - var(--lh) * 1em) / 2) 0;
}
.field .caret-native { caret-color: var(--blaze); }
.field [readonly] { color: var(--dim); }
.field input:-webkit-autofill,
.field input:-webkit-autofill:hover,
.field input:-webkit-autofill:focus {
  -webkit-text-fill-color: var(--phos);
  caret-color: var(--blaze);
  transition: background-color 99999s 0s;
}

/* Without JavaScript the inputs are plain lines with a visible caret and rule. */
html:not(.js) .field input,
html:not(.js) .field textarea { caret-color: var(--blaze); border-bottom: 1px solid var(--line); }
html:not(.js) .field textarea { min-height: calc(var(--hit) * 2); }

.blk {
  position: absolute;
  top: calc(var(--hit) / 2 - 0.6em);
  left: 0;
  width: 1ch;
  height: 1.2em;
  background: var(--blaze);
  box-shadow: var(--hot);
  pointer-events: none;
  animation: cs-blink 1.06s steps(1) infinite;
}
.blk.is-hollow { background: transparent; border: 1px solid var(--blaze); box-shadow: none; }
.blk.is-solid { animation: none; }

/* Key caps, like Mac Terminal's hints. The button is the 44px target;
   the cap inside it is the small visible key. */
.keys { display: none; gap: 0.5ch; flex: none; margin-left: auto; }
.js .row.is-current:not(.is-printing) .keys { display: flex; }
.keys--review { display: flex; gap: 1.5ch; margin-top: calc(var(--row) * 0.4); margin-left: 0; }

.key {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  margin: 0;
  padding: 0 2px;
  border: 0;
  border-radius: 0;
  background: transparent;
  color: var(--dim);
  font: inherit;
  font-size: calc(var(--fs) * 0.82);
  text-shadow: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.cap {
  display: inline-flex;
  align-items: center;
  gap: 0.5ch;
  padding: 2px 7px 2px 5px;
  border: 1px solid var(--faint);
  color: inherit;
  line-height: 1.3;
}
.cap svg { width: 1.05em; height: 1.05em; fill: none; stroke: currentColor; stroke-width: 1.3; stroke-linecap: square; }
.key:hover .cap { color: var(--phos); border-color: var(--dim); }
.key--go { color: var(--phos); }
.key--go .cap { border-color: var(--dim); }
.key--send { color: var(--blaze); }
.key--send .cap { border-color: var(--blaze); text-shadow: var(--hot); }
.key:focus-visible { outline: none; }
.key:focus-visible .cap { background: var(--blaze); border-color: var(--blaze); color: var(--void); text-shadow: none; }
.key[disabled] { cursor: default; }

.err { margin: 0; color: var(--phos); font-size: inherit; letter-spacing: 0; }
.err::before { content: "[ ! ] "; color: var(--blaze); text-shadow: var(--hot); }
.count { color: var(--faint-text); margin: 0; font-size: inherit; letter-spacing: 0; }
.ack { margin: calc(var(--row) * -0.2) 0 calc(var(--row) * 0.7); }

.review { margin: 0 0 calc(var(--row) * 0.5); }
.review dl { margin: calc(var(--row) * 0.2) 0 0; }
.review dl > div { display: grid; grid-template-columns: 10ch minmax(0, 1fr); column-gap: 1ch; }
.review dt { color: var(--faint-text); }
.review dd { margin: 0; color: var(--phos); overflow-wrap: anywhere; }

/* The consent line above transmit (K-6 as amended by the Kage). */
.consent { margin: calc(var(--row) * 0.4) 0 0; color: var(--dim); }
.consent .link { color: var(--dim); text-decoration-color: var(--faint); }
.consent .link:hover { color: var(--phos); }
.consent .link:focus-visible { outline: none; background: var(--blaze); color: var(--void); text-decoration: none; }

.nojs-send { margin: calc(var(--row) * 0.4) 0 0 2ch; }

.hint-fine { display: none; }
@media (pointer: fine) { .hint-fine { display: inline; } }

.sending, .after, .fail { margin-top: calc(var(--row) * 0.3); }
.after:focus, .fail:focus { outline: none; }
.fail .link { color: var(--phos); text-decoration-color: var(--dim); }

/* ── Footer: absent until the visitor scrolls, then it types out ── */

.foot {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 15;
  padding:
    0 calc(18px + env(safe-area-inset-right))
    calc(12px + env(safe-area-inset-bottom))
    calc(18px + env(safe-area-inset-left));
  background: var(--void);
  color: var(--faint-text);
  font-size: calc(var(--fs) * 0.92);
}
@media (min-width: 900px) {
  .foot { padding: 0 56px 18px max(56px, 7vw); }
}
.foot .rule {
  font-size: var(--fs); /* same dash size as the session rule (Kage 16:33 GST) */
  margin: 0 0 8px;
  line-height: 1;
  white-space: nowrap;
  overflow: hidden;
  max-width: none;
  color: var(--faint);
  letter-spacing: 0.08em;
}
.foot p { margin: 0; max-width: 80ch; }
.foot .link { display: inline-block; padding: 14px 0; margin: -14px 0; color: var(--dim); text-decoration: underline; text-decoration-color: var(--faint); text-underline-offset: 3px; }
.foot .link:hover { color: var(--phos); }
.foot .link:focus-visible { outline: none; background: var(--blaze); color: var(--void); text-decoration: none; }
.foot .fl { clip-path: inset(0 100% 0 0); white-space: pre-wrap; }
.foot .rule.fl { white-space: nowrap; }
.foot:not(.is-on) { background: transparent; }
.foot.is-on .fl { clip-path: inset(0 0 0 0); }
.foot:not(.is-on) { pointer-events: none; }
.foot.is-on { pointer-events: auto; }
body.foot-on .door { padding-bottom: var(--foot-h, 96px); }
/* Without JavaScript the footer is simply there, in the flow. */
html:not(.js) .foot { position: static; padding-left: 0; padding-right: 0; background: transparent; pointer-events: auto; margin-top: calc(var(--row) * 2); }
html:not(.js) .foot .fl { clip-path: none; }

/* ── Static pages: /privacy, the 404 and the no-JS responses ───── */

.page { max-width: 80ch; }
.page .top { margin: 0 0 calc(var(--row) * 1.5); }
/* The back key on /privacy (the Kage, 22 Oct 23:33Z): the session's key-cap look, a 44 px target,
   at the top and the bottom of the notice, so no visitor is stranded. */
.page .back { margin-left: -2px; text-decoration: none; }
.page .bottom { margin: calc(var(--row) * 2) 0 0; }
.page .top .link { color: var(--dim); text-decoration-color: var(--faint); text-transform: uppercase; letter-spacing: 0.24em; display: inline-block; padding: 12px 0; margin: -12px 0; }
.page h1 { margin: 0 0 calc(var(--row) * 0.5); font-size: calc(var(--fs) * 1.15); font-weight: 400; color: var(--phos); }
.page h2 { margin: calc(var(--row) * 1.6) 0 calc(var(--row) * 0.5); font-size: var(--fs); font-weight: 400; color: var(--phos); }
.page p, .page li { color: var(--light); max-width: 72ch; text-wrap: pretty; }
.page p + p { margin-top: calc(var(--row) * 0.6); }
.page .quiet { color: var(--dim); }
.page ul { margin: calc(var(--row) * 0.5) 0 calc(var(--row) * 0.6); padding-left: 2ch; list-style: none; }
.page li { position: relative; }
.page li::before { content: "-"; position: absolute; left: -2ch; color: var(--faint); }
.page li + li { margin-top: calc(var(--row) * 0.25); }
.page strong { font-weight: 400; color: var(--white); }
.page .link { overflow-wrap: anywhere; }
.page table { width: 100%; border-collapse: collapse; margin: calc(var(--row) * 0.6) 0; }
.page th, .page td { text-align: left; vertical-align: top; padding: 8px 1.5ch 8px 0; border-bottom: 1px solid var(--line-quiet); font-weight: 400; }
.page th { color: var(--dim); border-bottom-color: var(--line); }
.page td { color: var(--light); }
@media (max-width: 760px) {
  .page table, .page tbody, .page tr, .page td { display: block; width: 100%; }
  .page thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .page tr { padding: calc(var(--row) * 0.4) 0; border-bottom: 1px solid var(--line); }
  .page td { border: 0; padding: 2px 0; }
  .page td::before { content: attr(data-label); display: block; color: var(--dim); }
}
.page .ln--status { margin: 0 0 calc(var(--row) * 0.5); }
.page .ln { color: var(--phos); }

/* Typed text, cursors and cells never transition (the reduced-motion rule below would otherwise
   make visibility land a frame late). */
.vis, [data-type], .cell, .blk, .cursor, .foot .fl { transition: none !important; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
  }
}
