:root {
  /* Drawn from the scene: a navy night, aged gold like the lock, bronze
     shadows, silver-blue silk, and a touch of green patina */
  --bg: #0b0e18;
  --text: #efe6d4;   /* warm parchment */
  --dim: #8d97ab;    /* silver-blue, like the silk */
  --gold: #e3ae5f;   /* the lock */
  --bronze: #6e4c24; /* frames and quiet marks */
  --silver: #a9c6d8; /* headings and secondary actions */
  --patina: #6fa48d; /* success and completed states */
  --err: #e0644f;
  --silk: rgba(232, 222, 198, 0.6);
  --strand: #7f93a6;  /* panel frames, the same silver-blue as the web */
  --fs: 14px;
  --lh: 20px;
  color-scheme: dark;
}

* { box-sizing: border-box; }

html, body { background: var(--bg); }

body {
  margin: 0;
  font-family: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: var(--fs);
  line-height: var(--lh);
  color: var(--text);
}

pre, code { font-family: inherit; }
::selection { background: var(--gold); color: var(--bg); }

.gold { color: var(--gold); }
.dim { color: var(--dim); }

/* ---------- Layout: Arachne in the middle, panels on either side ---------- */

.layout {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-areas: "header" "stage" "intro" "panel";
  max-width: 820px;
  margin: 0 auto;
  padding-left: max(16px, env(safe-area-inset-left, 0px));
  padding-right: max(16px, env(safe-area-inset-right, 0px));
}
.site-header { grid-area: header; }
.stage { grid-area: stage; height: 56vh; } /* room to see Arachne before the panels */
.intro { grid-area: intro; }
.layout > main { grid-area: panel; min-width: 0; }

footer {
  position: relative;
  z-index: 1;
  max-width: 820px;
  margin: 0 auto;
  padding-left: max(16px, env(safe-area-inset-left, 0px));
  padding-right: max(16px, env(safe-area-inset-right, 0px));
}

/* Wide screens: the panels stack in a column on the left, in the dark open
   space; the lock, web and Arachne fill the stage on the right */
@media (min-width: 1100px) {
  .layout {
    max-width: none;
    grid-template-columns: minmax(360px, 500px) 1fr;
    grid-template-areas: "header stage" "intro stage" "panel stage";
    grid-template-rows: auto auto 1fr;
    column-gap: 2vw;
    align-items: start;
    padding-left: max(3vw, env(safe-area-inset-left, 0px));
    padding-right: max(3vw, env(safe-area-inset-right, 0px));
  }
  .stage { height: auto; }
  footer { max-width: none; padding-left: 3vw; padding-right: 3vw; }
}

/* ---------- Header ---------- */

.site-header { position: relative; padding-top: 32px; }
.prompt { margin: 0; color: var(--text); padding-right: 12ch; }
.prompt .host { color: var(--silver); }
.prompt .sigil { color: var(--gold); margin-right: 1ch; }
.cursor { color: var(--gold); animation: blink 1s steps(1) infinite; }

h1 {
  font-size: var(--fs);
  margin: var(--lh) 0 0;
  color: var(--gold);
  text-transform: uppercase;
  letter-spacing: 0.3ch;
}

.tagline, .hint { color: var(--dim); margin: 0; }
.tagline::before, .hint::before { content: "// "; color: var(--bronze); }

h2, h3 {
  font-size: var(--fs);
  margin: var(--lh) 0 calc(var(--lh) / 2);
  color: var(--silver);
  text-transform: uppercase;
}
h2:first-child { margin-top: 0; }
h2 { display: flex; gap: 1ch; }
h2::before { content: "##"; color: var(--bronze); }
/* a dotted leader runs from each heading to the edge of its panel */
h2::after {
  content: "o-----------------------o-----------------------------o--------------------------------------------";
  flex: 1;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
  color: var(--strand);
}
.status-head h2::after { content: none; }

/* -=*=- divider */
.rule {
  margin: var(--lh) 0 0;
  overflow: hidden;
  white-space: nowrap;
  color: var(--bronze);
}
.rule::before {
  content: "-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-=*=-";
}
h3::before { content: "### "; color: var(--bronze); }

/* Spider dangling from the top of the page on its thread */
.spider {
  position: absolute;
  top: 0;
  right: 16px;
  margin: 0;
  font-size: 12px;
  line-height: 1.1;
  color: var(--gold);
  text-shadow: 1px 0 var(--silver);
  transform-origin: top center;
  animation: dangle 4s ease-in-out infinite;
  user-select: none;
}

/* ---------- The scene behind the page (drawn by arachne.js) ---------- */

.arachne-art {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  background: #0b0e18;
  pointer-events: none;
}

/* The text sits right in the web. The scene (arachne.js) parts the strands
   around every line of text, so it stays readable without panels. */
.prompt, .site-header h1, .tagline { width: fit-content; }

/* Sections are spaced apart in the web, with room for strands between them */
.box.hang { margin-top: calc(var(--lh) * 3); }

/* ---------- ASCII boxes (borders drawn by ascii.js) ---------- */

/* .box keeps its spacing, but there are no panels: no backing and no frame */
.box {
  position: relative;
  background: transparent;
  margin: var(--lh) 0;
  padding: var(--lh) 3ch;
}
.layout .frame { display: none; }
.frame {
  position: absolute;
  top: 0;
  left: 0;
  margin: 0;
  font: inherit;
  line-height: var(--lh);
  color: var(--strand); /* frames are silk, like the web's strands */
  white-space: pre;
  pointer-events: none;
  user-select: none;
}
.frame b { color: var(--gold); }
.frame i { color: var(--gold); font-style: normal; }

/* ---------- Form widgets ---------- */

label { display: block; margin: calc(var(--lh) / 2) 0; color: var(--dim); }

/* each field hangs on a strand of silk, tied off with a dewdrop at each end */
.field { display: flex; align-items: flex-start; color: var(--strand); }
.field::before { content: "o-- "; white-space: pre; }
.field::after { content: " --o"; white-space: pre; }
.field.select::after { content: " v --o"; }
.field:focus-within { color: var(--gold); }
.field.invalid { color: var(--err); }

input, select, textarea {
  flex: 1;
  min-width: 0;
  font: inherit;
  line-height: var(--lh);
  color: var(--text);
  background: transparent;
  border: 0;
  padding: 0;
  margin: 0;
  outline: none;
  caret-color: var(--gold);
}
input::placeholder, textarea::placeholder { color: var(--dim); opacity: 0.6; }
select { appearance: none; cursor: pointer; }
select option { background: var(--bg); color: var(--text); }
textarea { resize: vertical; }

.toggle {
  position: relative;
  display: flex;
  cursor: pointer;
  color: var(--text);
  margin: 4px 0;
}
.toggle input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.toggle span::before { content: "[ ] "; color: var(--bronze); white-space: pre; }
.toggle input:checked + span::before { content: "[x] "; color: var(--gold); }
.toggle.radio span::before { content: "( ) "; }
.toggle.radio input:checked + span::before { content: "(*) "; }
.toggle input:focus-visible + span { outline: 1px dashed var(--silver); outline-offset: 2px; }

.btn {
  font: inherit;
  color: var(--silver);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  white-space: pre;
  text-transform: uppercase;
}
.btn::before { content: "[ "; }
.btn::after { content: " ]"; }
.btn:hover, .btn:focus-visible { background: var(--silver); color: var(--bg); outline: none; }
.btn.primary { color: var(--gold); font-weight: 700; margin-top: var(--lh); }
.btn.primary::after { content: " ] >>"; }
.btn.primary:hover, .btn.primary:focus-visible { background: var(--gold); color: var(--bg); }
.btn.icon { color: var(--dim); }
.btn.icon::before { content: "["; }
.btn.icon::after { content: "]"; }
.btn:disabled { opacity: 0.5; cursor: wait; }

/* The main button is knotted into the silk: o--( START AUDIT >> )--o */
.btn.box {
  display: block;
  width: 100%;
  margin: calc(var(--lh) / 2) 0 0;
  padding: calc(var(--lh) / 2) 2ch;
  text-align: center;
  background: transparent;
}
.btn.primary.box::before { content: "o--( "; }
.btn.primary.box::after { content: " )--o"; }
.btn.primary.box:hover, .btn.primary.box:focus-visible { background: var(--gold); color: var(--bg); }

.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 0 4ch; align-items: end; }

.seed-row {
  display: grid;
  grid-template-columns: 16ch 1fr auto auto;
  gap: 0 2ch;
  align-items: center;
  margin-bottom: 4px;
}
.seed-row .toggle { margin: 0; color: var(--dim); }

details { margin: var(--lh) 0; }
summary { cursor: pointer; color: var(--silver); list-style: none; text-transform: uppercase; }
summary::-webkit-details-marker { display: none; }
summary::before { content: "[+] "; color: var(--gold); }
details[open] summary::before { content: "[-] "; }
.sources { display: grid; grid-template-columns: repeat(auto-fill, minmax(26ch, 1fr)); gap: 0 2ch; margin-top: 8px; }

.errors { list-style: none; padding: 0; margin: var(--lh) 0 0; color: var(--err); }
.errors li::before { content: "!! "; }
.errors code { color: var(--text); }

/* ---------- Status view ---------- */

.status-head { display: flex; justify-content: space-between; align-items: baseline; gap: 2ch; flex-wrap: wrap; }
.status-head h2 { margin: 0; }
.status-head code { color: var(--gold); text-transform: none; }

.badge { color: var(--gold); text-transform: uppercase; }
.badge::before { content: "[ "; color: var(--bronze); }
.badge::after { content: " ]"; color: var(--bronze); }
.badge.complete { color: var(--patina); }

.spin { color: var(--silver); }
.spin::before { content: "|"; animation: spin 0.6s steps(1) infinite; }
.spin[hidden] { display: none; }
#signed-in[hidden], #signin-controls[hidden] { display: none; }
.signed-in { color: var(--gold); font-weight: 700; }
.signed-in strong { color: var(--silver); }

.bar { margin: var(--lh) 0 0; color: var(--gold); white-space: pre; overflow: hidden; }

.phases { list-style: none; padding: 0; display: flex; flex-wrap: wrap; gap: 0 1ch; color: var(--dim); }
.phases li.done { color: var(--patina); }
.phases li.active { color: var(--gold); }
.phases li + li::before { content: "-> "; color: var(--bronze); }

.counts { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--lh) 2ch; margin-top: var(--lh); }
.count { margin: 0; padding: calc(var(--lh) / 2) 2ch; text-align: center; }
/* the counts' labels used to live in their frames */
.count::before { content: attr(data-title); display: block; color: var(--dim); text-transform: uppercase; font-size: 12px; }
.digits { display: inline-block; margin: 0; text-align: left; line-height: var(--lh); color: var(--text); }

.list { list-style: none; padding: 0; margin: 0; }
.list li { margin-bottom: calc(var(--lh) / 2); }
.list .task { padding-left: 2ch; }
.events .tag { color: var(--silver); text-transform: uppercase; }
.events .tag::before { content: "["; }
.events .tag::after { content: "]"; }
.events .tag.finding { color: var(--gold); }
.events .tag.source_failed { color: var(--err); }

/* ---------- Arachne banner ---------- */

.arachne { text-align: center; container-type: inline-size; }
.arachne .hint { margin-top: var(--lh); font-size: 12px; }

.arachne-title {
  display: inline-block;
  text-align: left;
  margin: var(--lh) 0 0;
  font-size: min(15px, calc(100cqi / 30));
  line-height: 1.15;
  color: var(--gold);
  text-shadow: 2px 0 var(--silver);
  user-select: none;
}
.arachne-caption { max-width: 60ch; margin: var(--lh) auto 0; color: var(--dim); }

footer { color: var(--text); padding-bottom: calc(var(--lh) * 2); }

/* ---------- Animation ---------- */

@keyframes blink { 50% { opacity: 0; } }
@keyframes spin {
  0% { content: "|"; }
  25% { content: "/"; }
  50% { content: "-"; }
  75% { content: "\\"; }
}
@keyframes dangle {
  0%, 100% { transform: translateY(-6px) rotate(-3deg); }
  50% { transform: translateY(6px) rotate(3deg); }
}

@media (prefers-reduced-motion: reduce) {
  .spider, .cursor, .spin::before { animation: none; }
}

@media (max-width: 600px) {
  .spider { font-size: 10px; }
  .box { padding: var(--lh) 2ch; }
}

/* The form adapts to its own width, since it sits in a narrow side column on wide screens */
#form-view { container-type: inline-size; }
@container (max-width: 520px) {
  .grid-2 { grid-template-columns: 1fr; }
  .seed-row { grid-template-columns: 1fr auto auto; margin-bottom: calc(var(--lh) / 2); }
  .seed-row .field.select { grid-column: 1 / -1; }
}

/* recorded audits the owner can replay */
.replay-list { list-style: none; padding: 0; margin: 0 0 var(--lh); }
.replay-list li { margin: 4px 0; }
.replay-list .hint::before { content: " "; }

#result { margin-top: var(--lh); }
#result .report-grade { font-size: 1.2em; }
#result a { word-break: break-all; }
