/*
 * SEKTOR-7 — the UI is the Custodian.
 *
 * Palette is the measured one from design-catalog.md §2. Nothing here may exceed
 * the chroma budget: rust #8B563D and status-green #49634C are the only two
 * chromatic notes in the entire game and they never appear together.
 *
 * Typographic rule that carries the voice design:
 *   Custodian — monospace, no speaker label. It has no name because it is the page.
 *   Elias     — serif, labelled. He is the only *other* in the game.
 */

:root {
  --paper-hi:   #FAF8F1;
  --paper:      #F5F1E6;
  --paper-lo:   #F0EADD;
  --drab-lt:    #D5D1C8;
  --grey-mid:   #9E9B95;
  --drab:       #7E786D;
  --slate:      #525754;
  --shadow:     #454541;
  --deep:       #363939;
  --mass:       #292A29;
  --ink:        #101110;

  --rust:       #8B563D;  /* Elias. Never on machines. */
  --green:      #49634C;  /* Machines. Never on Elias. */
  --gold:       #967F4B;  /* Signage only. */

  --mono: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, Consolas, monospace;
  --serif: "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;

  --measure: 68ch;
}

* { box-sizing: border-box; }

/* An ID selector outranks the UA stylesheet's `[hidden] { display: none }`, so
   #minigame/#choices would paint even while hidden. Keep this above them. */
[hidden] { display: none !important; }

html, body {
  height: 100%;
  margin: 0;
}

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  display: grid;
  place-items: center;
  padding: clamp(0.75rem, 2vw, 2rem);
  /* Paper grain — reads *through* everything, per the style bible. Inline, no external assets. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)' opacity='0.06'/%3E%3C/svg%3E");
}

#app {
  width: min(105ch, 100%);
  display: flex;
  flex-direction: column;
  gap: clamp(0.75rem, 1.5vw, 1.25rem);
}

/* ─── Title ─────────────────────────────────────────────────────────────────
   The Custodian idling. Backed by the style anchor — the empty city that works.
   The status block ends on "Belegung — null", which the game's first turn
   answers with "Belegung: eins." Do not add a tagline; the status block is the
   tagline. */

#title {
  width: min(105ch, 100%);
  aspect-ratio: 3 / 2;  /* matches the plate frame — the title is backed by the style anchor */
  position: relative;
  border: 1px solid var(--ink);
  outline: 1px solid var(--ink);
  outline-offset: 3px;
  overflow: hidden;
  background-color: var(--paper-lo);
  background-image:
    linear-gradient(
      100deg,
      color-mix(in srgb, var(--paper) 94%, transparent) 0 34%,
      color-mix(in srgb, var(--paper) 70%, transparent) 46%,
      color-mix(in srgb, var(--paper) 8%, transparent) 68%
    ),
    url("../assets/plates/plate_overlook_empty.png");
  background-size: cover, cover;
  background-position: center, center;
  display: flex;
  align-items: center;
}

#title-card {
  padding: clamp(1.25rem, 4vw, 3.25rem);
  max-width: 46ch;
}

.title-kicker {
  font-family: var(--mono);
  font-size: 0.64rem;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--drab);
  margin: 0 0 0.5rem;
}

#title h1 {
  font-family: var(--mono);
  font-weight: 400;
  font-size: clamp(1.6rem, 5.2vw, 3.2rem);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0;
  line-height: 1;
  /* The hyphen is a break opportunity — without this the title renders as
     "SEKTOR-" / "7". It must never wrap. */
  white-space: nowrap;
}

.title-sub {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  color: var(--slate);
  margin: 0.7rem 0 1.5rem;
}

#title-status {
  margin: 0 0 1.75rem;
  border-top: 1px solid var(--drab-lt);
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.08em;
}
#title-status > div {
  display: flex;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.38rem 0;
  border-bottom: 1px solid var(--drab-lt);
}
#title-status dt { color: var(--drab); text-transform: uppercase; }
#title-status dd {
  margin: 0;
  color: var(--slate);
  text-transform: uppercase;
}
#title-status dd.warn { color: var(--ink); }
/* The last line is the hook. Let it carry weight. */
#title-status > div:last-child dt,
#title-status > div:last-child dd { color: var(--ink); }

#title-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.55rem;
}

#title-actions button {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--paper-hi);
  border: 1px solid var(--ink);
  padding: 0.72rem 1.3rem;
  cursor: pointer;
  transition: background 100ms linear, box-shadow 100ms linear;
}
#title-actions button:hover,
#title-actions button:focus-visible {
  background: var(--paper-lo);
  outline: none;
  box-shadow: inset 3px 0 0 var(--rust);
}
#title-actions #start { border-color: var(--slate); color: var(--slate); }

/* On a phone a 16:9 box is ~214px tall and cannot hold the title, the status
   block and the button — the button ended up outside the card. Let it grow. */
@media (max-width: 560px) {
  #title {
    aspect-ratio: auto;
    min-height: 30rem;
    background-image:
      linear-gradient(
        180deg,
        color-mix(in srgb, var(--paper) 92%, transparent) 0 62%,
        color-mix(in srgb, var(--paper) 30%, transparent) 100%
      ),
      url("../assets/plates/plate_overlook_empty.png");
    background-position: center, center bottom;
  }
  #title-card { max-width: none; }
}

/* ─── The plate ─────────────────────────────────────────────────────────── */

#plate {
  position: relative;
  margin: 0;
  /* 3:2 — the native frame of the GPT-Image-2 plate set (1536×1024). At 16:9,
     object-fit: cover cropped ~11% off top and bottom and clipped full-body shots. */
  aspect-ratio: 3 / 2;
  background: var(--paper-lo);
  border: 1px solid var(--ink);
  outline: 1px solid var(--ink);
  outline-offset: 3px;   /* the double-rule of a technical plate */
  overflow: hidden;
}

#plate-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
#plate-img:not([src]), #plate-img[src=""] { display: none; }

#plate-placeholder {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 0.6rem;
  font-family: var(--mono);
  background:
    repeating-linear-gradient(
      45deg,
      transparent 0 11px,
      color-mix(in srgb, var(--drab-lt) 55%, transparent) 11px 12px
    );
}

.ph-label {
  font-size: 0.7rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--drab);
}

.ph-id {
  font-size: clamp(0.85rem, 2vw, 1.15rem);
  letter-spacing: 0.06em;
  color: var(--slate);
  border: 1px dashed var(--grey-mid);
  background: var(--paper);
  padding: 0.45rem 0.9rem;
}

#plate-caption {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  font-family: var(--mono);
  font-size: 0.62rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--drab);
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  border-top: 1px solid var(--drab-lt);
  padding: 0.3rem 0.6rem;
  display: flex;
  justify-content: space-between;
}

/* ─── The text box ──────────────────────────────────────────────────────── */

#box {
  border: 1px solid var(--ink);
  background: var(--paper-hi);
  padding: clamp(0.9rem, 2vw, 1.4rem);
  min-height: 8.5rem;
  position: relative;
  cursor: pointer;
}

#speaker {
  font-family: var(--mono);
  font-size: 0.64rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--rust);
  margin-bottom: 0.55rem;
  min-height: 0.9rem;
}
/* The Custodian gets no label. It is not a character in the scene; it is the scene. */
#box[data-speaker="custodian"] #speaker,
#box[data-speaker="none"] #speaker { visibility: hidden; }

#text {
  margin: 0;
  max-width: var(--measure);
  font-size: clamp(1rem, 1.15vw + 0.72rem, 1.2rem);
  line-height: 1.65;
  white-space: pre-wrap;
}

/* Custodian: the machine's log, printing. */
#box[data-speaker="custodian"] #text {
  font-family: var(--mono);
  font-size: clamp(0.86rem, 0.9vw + 0.62rem, 1rem);
  line-height: 1.75;
  letter-spacing: 0.01em;
  color: var(--mass);
}

/* Elias: a human voice. */
#box[data-speaker="elias"] #text {
  font-family: var(--serif);
  color: var(--ink);
}

/* Stage direction — the record describing itself. */
#box[data-speaker="none"] #text {
  font-style: italic;
  color: var(--slate);
}

#advance {
  position: absolute;
  right: 0.9rem;
  bottom: 0.7rem;
  width: 0.5rem;
  height: 0.5rem;
  background: var(--ink);
  opacity: 0;
  transition: opacity 120ms linear;
}
#box[data-done="true"] #advance {
  opacity: 1;
  animation: blink 1.1s steps(1, end) infinite;
}
@keyframes blink { 50% { opacity: 0.15; } }

/* ─── Choices ───────────────────────────────────────────────────────────── */

#choices {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

#choices button {
  font-family: var(--mono);
  font-size: clamp(0.8rem, 0.75vw + 0.62rem, 0.92rem);
  line-height: 1.55;
  text-align: left;
  color: var(--ink);
  background: var(--paper-hi);
  border: 1px solid var(--slate);
  padding: 0.75rem 0.95rem;
  cursor: pointer;
  transition: background 100ms linear, border-color 100ms linear;
}

#choices button:hover,
#choices button:focus-visible {
  background: var(--paper-lo);
  border-color: var(--ink);
  outline: none;
  box-shadow: inset 3px 0 0 var(--rust);
}

/* ─── Minigame ──────────────────────────────────────────────────────────── */

#minigame {
  width: 100%;
  aspect-ratio: 16 / 7;
  border: 1px solid var(--ink);
  background: var(--paper-hi);
  display: block;
  cursor: pointer;
  margin-bottom: 2.5rem;  /* keep the canvas off the page edge */
}

/* ─── Ending ────────────────────────────────────────────────────────────── */

#ending {
  border: 1px solid var(--ink);
  outline: 1px solid var(--ink);
  outline-offset: 3px;
  background: var(--paper-hi);
  padding: clamp(1.5rem, 4vw, 2.75rem);
  text-align: center;
}

.ending-kicker {
  font-family: var(--mono);
  font-size: 0.64rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--drab);
}

#ending h1 {
  font-family: var(--mono);
  font-size: clamp(1.4rem, 4vw, 2.1rem);
  font-weight: 400;
  letter-spacing: 0.3em;
  margin: 0.75rem 0 1.75rem;
  color: var(--ink);
}

#ending button, #reset {
  font-family: var(--mono);
  font-size: 0.7rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--drab);
  background: transparent;
  border: 1px solid var(--drab-lt);
  padding: 0.5rem 1rem;
  cursor: pointer;
}
#ending button:hover, #reset:hover {
  color: var(--ink);
  border-color: var(--ink);
}

/* The Custodian wiping its own record. Present, findable, never shouting —
   and armed→confirm, because a stray click costs a whole playthrough. */
#reset {
  position: fixed;
  right: 1rem;
  bottom: 1rem;
  background: var(--paper-hi);
  border-color: var(--grey-mid);
  color: var(--slate);
  opacity: 0.75;
  transition: opacity 120ms linear, color 120ms linear, border-color 120ms linear;
}
#reset:hover, #reset:focus-visible {
  opacity: 1;
  color: var(--ink);
  border-color: var(--ink);
  outline: none;
}
#reset[data-armed="true"] {
  opacity: 1;
  color: var(--rust);
  border-color: var(--rust);
  box-shadow: inset 2px 0 0 var(--rust);
}

@media (prefers-reduced-motion: reduce) {
  #box[data-done="true"] #advance { animation: none; }
}
