/*
 * Reign of Companions — the entire visual identity, in CSS.
 *
 * No images, no icon font, no web font. Partly because the CSP is
 * `default-src 'none'` and a policy you keep loosening is one you will
 * eventually loosen too far — and partly because it settles the EverQuest
 * asset question by not having any assets. WEB-COMPANION-PLAN.md §5: the game's
 * art belongs to Daybreak/Darkpaw, and a free public site is still
 * distribution. Names and mechanics are facts; icons and maps are theirs.
 *
 * The look is meant to feel like a fantasy console without borrowing one:
 * deep slate, a warm brass accent, generous spacing, system fonts.
 */

:root {
  --bg:        #12141a;
  --bg-raise:  #191c24;
  --line:      #2a2f3b;
  --ink:       #e6e8ee;
  --ink-dim:   #9aa1b2;
  --brass:     #d9a441;
  --brass-dim: #8a6a2c;
  --good:      #6fbf73;
  --warn:      #d9a441;
  --bad:       #e06c62;
  --unknown:   #7fa8d9;
  --radius:    10px;
  --measure:   62ch;
}

@media (prefers-color-scheme: light) {
  :root {
    --bg:       #f7f5f1;
    --bg-raise: #fffdfa;
    --line:     #e0dad0;
    --ink:      #23262e;
    --ink-dim:  #5d6472;
    --brass:    #8a6a2c;
  }
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 16px/1.65 system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  /* A slow radial wash so the page is not a flat rectangle. Costs nothing. */
  background-image:
    radial-gradient(900px 420px at 12% -8%, rgba(217,164,65,.10), transparent 60%),
    radial-gradient(700px 380px at 92% 4%, rgba(127,168,217,.07), transparent 60%);
  background-attachment: fixed;
}

.skip {
  position: absolute; left: -9999px;
  background: var(--brass); color: #000; padding: .6rem 1rem; border-radius: 0 0 var(--radius) 0;
}
.skip:focus { left: 0; top: 0; z-index: 10; }

/* ------------------------------------------------------------------ chrome */
.bar {
  display: flex; align-items: center; gap: .75rem;
  padding: 1rem clamp(1rem, 4vw, 2.5rem);
  border-bottom: 1px solid var(--line);
  background: color-mix(in srgb, var(--bg-raise) 80%, transparent);
}
.bar nav { margin-left: auto; display: flex; gap: 1rem; align-items: center; }

/* The "logo": two nested rings. Abstract on purpose — a companion beside a
   player, if you like, or nothing at all. */
.mark {
  width: 22px; height: 22px; flex: 0 0 auto; position: relative;
}
.mark::before, .mark::after {
  content: ""; position: absolute; border-radius: 50%; border: 2px solid var(--brass);
}
.mark::before { inset: 0 8px 0 0; }
.mark::after  { inset: 0 0 0 8px; border-color: var(--brass-dim); }

.wordmark {
  font-weight: 650; letter-spacing: .02em; color: var(--ink);
  text-decoration: none;
}

/* -------------------------------------------------------------- structure */
main {
  max-width: 68ch;
  margin: 0 auto;
  padding: clamp(1.5rem, 5vw, 3.5rem) clamp(1rem, 4vw, 2.5rem) 4rem;
}
p, li { max-width: var(--measure); }

h1 {
  font-size: clamp(1.7rem, 4.5vw, 2.5rem);
  line-height: 1.2; letter-spacing: -.015em; margin: 0 0 .75rem;
}
h1 em { color: var(--brass); font-style: normal; }
h2 { font-size: 1.15rem; margin: 0 0 .6rem; letter-spacing: .01em; }

.lede { font-size: 1.08rem; color: var(--ink-dim); }
.muted { color: var(--ink-dim); }

.hero { margin-bottom: 2.5rem; }

.panel {
  background: var(--bg-raise);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 1.25rem 1.4rem;
  margin: 1.25rem 0;
}
.panel.assurance { border-left: 3px solid var(--brass); }

.steps { margin: 0; padding-left: 1.3rem; }
.steps li { margin: .45rem 0; }
.steps.tight li { margin: .25rem 0; }

code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: .92em;
  background: color-mix(in srgb, var(--brass) 14%, transparent);
  color: var(--brass);
  padding: .1em .4em; border-radius: 4px;
}

/* ------------------------------------------------------------------ forms */
.cta { display: flex; flex-wrap: wrap; gap: .9rem; align-items: center; margin-top: 1.5rem; }
.cta-note { color: var(--ink-dim); font-size: .92rem; }

.btn {
  display: inline-block; cursor: pointer;
  font: inherit; font-weight: 600;
  padding: .7rem 1.15rem; border-radius: var(--radius);
  border: 1px solid var(--line); background: transparent; color: var(--ink);
  text-decoration: none;
}
.btn.primary { background: var(--brass); border-color: var(--brass); color: #17130a; }
.btn:hover { filter: brightness(1.08); }
.btn:disabled { opacity: .55; cursor: default; filter: none; }

/* Never remove the focus ring — keyboard users need to see where they are. */
.btn:focus-visible, a:focus-visible, input:focus-visible, button:focus-visible {
  outline: 2px solid var(--brass); outline-offset: 2px;
}

.form label { display: block; font-weight: 600; margin-bottom: .4rem; }

#code {
  width: 100%; max-width: 22ch;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 1.5rem; letter-spacing: .22em; text-transform: uppercase;
  padding: .6rem .75rem;
  background: var(--bg); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--radius);
}
#code::placeholder { color: var(--ink-dim); opacity: .5; letter-spacing: .22em; }

.help { color: var(--ink-dim); font-size: .9rem; margin: .5rem 0 1.1rem; }

/* ---------------------------------------------------------------- results */
.result {
  margin-top: 1.25rem; padding: 1rem 1.15rem;
  border-radius: var(--radius); border: 1px solid var(--line);
  border-left-width: 3px; background: var(--bg-raise);
}
.result p { margin: .4rem 0 0; color: var(--ink-dim); }
.result.good    { border-left-color: var(--good); }
.result.warn    { border-left-color: var(--warn); }
.result.bad     { border-left-color: var(--bad); }
/* Visually distinct from `bad` on purpose: "we do not know" is not "it
   failed", and the colour should not tell the player it was. */
.result.unknown { border-left-color: var(--unknown); }
.result.busy    { border-left-color: var(--ink-dim); }

/* ----------------------------------------------------------------- footer */
footer {
  border-top: 1px solid var(--line);
  padding: 1.5rem clamp(1rem, 4vw, 2.5rem) 3rem;
  color: var(--ink-dim); font-size: .875rem;
}
footer p { max-width: var(--measure); margin: 0 auto; }

@media (prefers-reduced-motion: no-preference) {
  .btn { transition: filter .12s ease; }
}

/* ==========================================================================
   THE CONSOLE (console.html)
   Still no images and no icon font. The character-sheet feel comes from
   spacing and a brass rule, not from Daybreak's art - WEB-COMPANION-PLAN.md §5.
   ========================================================================== */

.sheet {
  display: flex; flex-wrap: wrap; gap: 1.5rem; align-items: flex-start;
  justify-content: space-between;
  background: var(--bg-raise); border: 1px solid var(--line);
  border-left: 3px solid var(--brass);
  border-radius: var(--radius); padding: 1.25rem 1.4rem; margin-bottom: 1.5rem;
}
.sheet-id h1 { font-size: 1.6rem; margin: 0; }
.sheet-id p { margin: .2rem 0 0; }

.vitals { display: flex; flex-wrap: wrap; gap: 1.4rem; margin: 0; }
.vitals div { margin: 0; }
.vitals dt {
  color: var(--ink-dim); font-size: .74rem; text-transform: uppercase;
  letter-spacing: .08em; margin-bottom: .15rem;
}
.vitals dd { margin: 0; font-size: 1.05rem; font-variant-numeric: tabular-nums; }
.vitals dd.on  { color: var(--good); }
.vitals dd.off { color: var(--ink-dim); }

/* ------------------------------------------------------------------- tabs */
.tabs {
  display: flex; flex-wrap: wrap; gap: .3rem;
  border-bottom: 1px solid var(--line); margin-bottom: 1.25rem;
}
.tab {
  appearance: none; background: none; border: 0;
  border-bottom: 2px solid transparent;
  color: var(--ink-dim); font: inherit; font-size: .95rem; cursor: pointer;
  padding: .6rem .9rem; margin-bottom: -1px;
}
.tab:hover { color: var(--ink); }
.tab.on { color: var(--brass); border-bottom-color: var(--brass); font-weight: 600; }

/* --------------------------------------------------------------- listings */
.items { list-style: none; margin: 0 0 1.4rem; padding: 0; }
.items .item {
  display: flex; flex-wrap: wrap; gap: .5rem 1rem; align-items: baseline;
  padding: .45rem .1rem; border-bottom: 1px solid var(--line);
}
.items .item:last-child { border-bottom: 0; }
.items .slot {
  color: var(--ink-dim); font-size: .8rem; min-width: 13ch;
  text-transform: uppercase; letter-spacing: .05em;
}
.items .iname { flex: 1 1 18ch; }
.items .meta {
  color: var(--ink-dim); font-size: .85rem; font-variant-numeric: tabular-nums;
}
.items .empty { color: var(--ink-dim); font-style: italic; padding: .45rem .1rem; }

.stats { display: flex; flex-wrap: wrap; gap: .9rem 1.8rem; margin: 0 0 1.4rem; }
.stats div { margin: 0; }
.stats dt { color: var(--ink-dim); font-size: .78rem; }
.stats dd { margin: 0; font-variant-numeric: tabular-nums; }

.cards {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: 1rem;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
}
.cards .card {
  background: var(--bg); border: 1px solid var(--line);
  border-radius: var(--radius); padding: .9rem 1rem;
}
.cards .card h3 { margin: 0 0 .15rem; font-size: 1.05rem; color: var(--brass); }
.cards .card p { margin: 0 0 .7rem; font-size: .9rem; }
.cards .card .stats { gap: .5rem 1.1rem; margin: 0; }

/* -------------------------------------------------------------- activity */
.events { list-style: none; margin: 0; padding: 0; }
.events .event {
  display: flex; flex-wrap: wrap; gap: .5rem 1rem; align-items: baseline;
  padding: .4rem .1rem; border-bottom: 1px solid var(--line);
}
.events .event:last-child { border-bottom: 0; }
.events .at {
  color: var(--ink-dim); font-size: .82rem; min-width: 21ch;
  font-variant-numeric: tabular-nums;
}
.events .what { flex: 1 1 16ch; }
.events .empty { color: var(--ink-dim); font-style: italic; padding: .4rem .1rem; }

/* Provenance. `unknown` is deliberately visible and deliberately NOT styled
   as a warning: it says the event predates provenance stamping, which is not
   a fault the player caused or can fix. */
.tag {
  font-size: .7rem; text-transform: uppercase; letter-spacing: .08em;
  padding: .12rem .5rem; border-radius: 999px; border: 1px solid var(--line);
  color: var(--ink-dim);
}
/* -------------------------------------------------------------- gear move */
.items .move { margin-left: auto; }
.items .move select { font-size: .82rem; padding: .15rem .4rem; }
/* The offline banner is informational, not an alarm: being logged in is the
   normal state, not a fault. */
#gear-state { border-left: 3px solid var(--line); padding-left: .7rem; }
#gear-result { margin-bottom: 1rem; }

/* ----------------------------------------------------------------- quests */
.quests { list-style: none; margin: 0 0 1.4rem; padding: 0; }
.quests .quest {
  background: var(--bg); border: 1px solid var(--line);
  border-radius: var(--radius); padding: .9rem 1rem; margin-bottom: .8rem;
}
.quest-head {
  display: flex; gap: 1rem; align-items: baseline; justify-content: space-between;
}
.quest-head h3 { margin: 0; font-size: 1.05rem; color: var(--brass); }
.quest-progress {
  color: var(--ink-dim); font-size: .85rem; font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.quests .quest p { margin: .35rem 0 .6rem; font-size: .92rem; }
.quests .reward { color: var(--good); font-size: .88rem; margin-bottom: 0; }

.objectives { list-style: none; margin: 0; padding: 0; }
.objectives .objective {
  display: flex; flex-wrap: wrap; gap: .5rem .8rem; align-items: baseline;
  padding: .25rem 0; font-size: .92rem;
}
.objectives .box { color: var(--ink-dim); width: 1.2em; }
/* A finished objective is dimmed, not struck through: strikethrough on a
   quest step reads as cancelled rather than done. */
.objectives .done { color: var(--ink-dim); }
.objectives .done .box { color: var(--good); }
.objectives .what { flex: 1 1 18ch; }
.objectives .meta {
  color: var(--ink-dim); font-size: .82rem; font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------------- chat */
.chat { list-style: none; margin: 0; padding: 0; }
.chat .line {
  display: flex; flex-wrap: wrap; gap: .4rem .8rem; align-items: baseline;
  padding: .35rem .1rem .35rem .6rem; border-bottom: 1px solid var(--line);
  border-left: 2px solid transparent;
}
.chat .line:last-child { border-bottom: 0; }
/* Outbound is marked so a player can scan for their own voice. Inbound is the
   default because most of a log is other people. */
.chat .line.out { border-left-color: var(--brass-dim); }
.chat .at {
  color: var(--ink-dim); font-size: .78rem; min-width: 20ch;
  font-variant-numeric: tabular-nums;
}
.chat .who { color: var(--brass); font-size: .88rem; min-width: 12ch; }
.chat .said { flex: 1 1 20ch; }
.chat .empty { color: var(--ink-dim); font-style: italic; padding: .4rem .1rem; }

.tag.chan { color: var(--ink-dim); }
/* Tells are marked as private on screen, not hidden. The player already knows
   they sent them; what they may not know is that they were recorded. */
.tag.chan-private { color: var(--warn); border-color: var(--warn); }

select {
  background: var(--bg); color: var(--ink); border: 1px solid var(--line);
  border-radius: 6px; padding: .3rem .5rem; font: inherit; font-size: .9rem;
}

/* A panel the server had to trim. Warn-coloured because an incomplete list
   presenting itself as complete is the thing being corrected. */
.trunc {
  border-left: 3px solid var(--warn); padding-left: .7rem;
  color: var(--ink); margin-bottom: 1rem;
}

.tag-human   { color: var(--good);    border-color: var(--good); }
.tag-ai      { color: var(--unknown); border-color: var(--unknown); }
.tag-system  { color: var(--brass);   border-color: var(--brass-dim); }
.tag-unknown { color: var(--ink-dim); border-color: var(--line); }

@media (max-width: 34rem) {
  .items .slot, .events .at { min-width: 0; flex-basis: 100%; }
  .vitals { gap: 1rem; }
}
