/* ============================================================================
   HUSTLE CORNERS — style.css
   The office is the page, so this file dresses a heads-up display, not a
   document. Every colour is one the generator itself uses (scene/palette.json):
   the room is Sky walls, Marble floor, #101018 outlines, #1e1c34 shell, and the
   two monitor glows #5ad0ff / #2dff9e; the HUD is those, and nothing else.
   ========================================================================= */

/* the chunky pixel display face, vendored — no runtime CDN, 16 KB for both cuts */
@font-face {
  font-family: "Silkscreen";
  src: url("vendor/silkscreen-400.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Silkscreen";
  src: url("vendor/silkscreen-700.woff2") format("woff2");
  font-weight: 700; font-style: normal; font-display: swap;
}

:root {
  --ink:      #101018;   /* the generator's outline colour */
  --shell:    #1e1c34;   /* its shell base */
  --sky:      #cce4f8;   /* Walls · Sky, wall_l */
  --sky-2:    #b8d6f0;   /* Walls · Sky, wall_r */
  --slate:    #5a7a9a;   /* Walls · Sky, trim */
  --beam:     #3a4e6a;   /* Walls · Sky, beam */
  --marble:   #f0eee8;   /* Floor · Marble */
  --marble-2: #d8d4cc;
  --glow:     #5ad0ff;   /* the left monitor */
  --glow-2:   #2dff9e;   /* the right monitor */
  --gold:     #ffd24a;   /* the desk lamp and the sconces */
  --sunset:   #ffb070;   /* the left window */
  --brick:    #c8703a;   /* the plant pot */
  --err:      #ff6a6a;
  --panel:    rgba(16, 16, 24, 0.92);
  --edge:     #3a4e6a;

  --display: "Silkscreen", "Courier New", ui-monospace, monospace;
  --body: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, "Cascadia Mono", "SF Mono", Consolas, "Liberation Mono", monospace;

  --pad: max(14px, env(safe-area-inset-left));
}

* { box-sizing: border-box; }

/* several panels below are laid out with display:grid / display:flex, and an
   author rule beats the UA's [hidden] no matter how specific it is — so say it
   once, loudly, and let every panel use the hidden attribute honestly. */
[hidden] { display: none !important; }

html, body {
  height: 100%;
  margin: 0;
  overflow: hidden;                 /* the page never scrolls; the room does the moving */
  overscroll-behavior: none;
  background: var(--ink);
  color: var(--marble);
  font: 400 15px/1.5 var(--body);
  -webkit-text-size-adjust: 100%;
}
body { position: fixed; inset: 0; touch-action: none; }

.display { font-family: var(--display); font-weight: 400; letter-spacing: 0.02em; }

button { font: inherit; color: inherit; cursor: pointer; }
a { color: var(--glow); }

/* ------------------------------------------------------------- the canvas */
#stage {
  position: fixed; inset: 0;
  width: 100%; height: 100%;
  display: block;
  touch-action: none;
  cursor: grab;
  background: var(--ink);
}
#stage.locked { cursor: none; }
#stage.dragging { cursor: grabbing; }
body.flat-on #stage { display: none; }

/* ------------------------------------------------- the still-frame fallback */
.flat {
  position: fixed; inset: 0;
  display: grid; place-items: center;
  padding: 76px 12px 220px;
  background:
    radial-gradient(120% 90% at 50% 32%, #2a3550 0%, var(--ink) 72%);
  overflow: auto;
}
.flat-in {
  position: relative;
  width: min(92vw, 74vh, 720px);
  aspect-ratio: 1;
  image-rendering: pixelated;
  border: 3px solid var(--ink);
  outline: 2px solid var(--beam);
  background: #fff;
}
.flat-in img { width: 100%; height: 100%; display: block; image-rendering: pixelated; }
.flat-spots { position: absolute; inset: 0; }
.flat-spots button {
  position: absolute;
  border: 2px solid transparent;
  background: transparent;
  padding: 0;
  transition: border-color .12s, background .12s;
}
.flat-spots button:hover,
.flat-spots button:focus-visible { border-color: var(--gold); background: rgba(255, 210, 74, 0.16); outline: none; }
.flat-note {
  position: fixed; left: 50%; transform: translateX(-50%); bottom: 8px;
  margin: 0; font: 400 11px/1 var(--display); color: var(--slate); letter-spacing: .08em;
}

/* ================================================================= the HUD */
/* The HUD floats over the room, so only the parts you can actually press may
   swallow a click — a wrapper's bounding box must not steal the pointer from
   the office behind it. */
.hud { position: fixed; inset: 0; pointer-events: none; z-index: 5; }
.hud > * { pointer-events: auto; }
.hud-tl, .hud-tr, .hud-bl { pointer-events: none; }
.hud-tr button, .hud-tr a, .stick { pointer-events: auto; }
.hint { pointer-events: none; }

.hud-tl { position: absolute; top: var(--pad); left: var(--pad); max-width: min(58vw, 420px); }
.hud-tr {
  position: absolute; top: var(--pad); right: var(--pad); text-align: right;
  display: flex; flex-direction: column; align-items: flex-end;
}

.brand {
  margin: 0 0 8px;
  font-family: var(--display);
  font-size: clamp(15px, 2.4vw, 22px);
  line-height: 1;
  color: var(--marble);
  text-shadow: 2px 2px 0 var(--ink), -1px -1px 0 var(--ink), 1px -1px 0 var(--ink), -1px 1px 0 var(--ink);
}
.brand span { color: var(--gold); margin-left: .5em; }

.chip {
  display: inline-flex; align-items: center; gap: 8px;
  margin: 0 0 6px;
  padding: 6px 10px;
  background: var(--panel);
  border: 2px solid var(--edge);
  color: var(--sky);
  font-size: 11.5px;
  letter-spacing: .06em;
  text-transform: uppercase;
}
/* the one chip that is a button: the traits drawer */
.chip-info { text-align: left; gap: 7px; }
.chip-info:hover, .chip-info:focus-visible { border-color: var(--gold); outline: none; }
.chip-info:hover .chip-v { color: var(--gold); }
.chip-k { color: var(--slate); font-size: 10px; }
.chip-v { color: var(--marble); font-weight: 600; font-size: 10.5px; }
.chip-i {
  font: 700 10px/14px var(--display);
  width: 15px; height: 15px; text-align: center; flex: none;
  border: 2px solid var(--gold); color: var(--gold);
}
.chip-net { color: var(--slate); font-size: 10.5px; }
.chip-count { gap: 6px; }
.chip-count b { font-size: 15px; color: var(--gold); }
.chip-count span { color: var(--slate); font-size: 10px; }

.led {
  width: 8px; height: 8px; background: var(--slate); border: 1px solid var(--ink);
  flex: none;
}
.led.on { background: var(--glow-2); }
.led.blink { background: var(--glow); animation: blink 1.6s steps(1) infinite; }
.led.hot { background: var(--err); }
@keyframes blink { 50% { opacity: .25; } }

.hud-links { margin: 2px 0 0; display: flex; gap: 10px; justify-content: flex-end; }
.hud-links a {
  font: 400 10px/1 var(--display); letter-spacing: .06em;
  color: var(--slate); text-decoration: none;
  padding: 5px 7px; background: var(--panel); border: 2px solid var(--edge);
}
.hud-links a:hover { color: var(--gold); border-color: var(--gold); }

/* --------------------------------------------------------- the crosshair
   Always on, because it is how you aim in here. Over a clickable object it
   grows and turns gold and the object names itself beside it, so you can tell
   scenery from something to read without clicking to find out. */
.cross {
  position: absolute; inset: 0;
  display: grid; place-items: center;
  pointer-events: none;
}
.cross i {
  width: 12px; height: 12px; flex: none;
  border: 2px solid rgba(240, 238, 232, .7);
  box-shadow: 0 0 0 2px rgba(16, 16, 24, .55);
  transition: width .12s ease, height .12s ease, border-color .12s ease, transform .12s ease;
}
.cross.on i {
  width: 20px; height: 20px;
  border-color: var(--gold);
  box-shadow: 0 0 0 2px rgba(16, 16, 24, .7), 0 0 10px rgba(255, 210, 74, .55);
  transform: rotate(45deg);
}
/* the label rides beside the crosshair without moving it: the crosshair itself
   has to stay on the exact centre pixel, because that is what the ray uses */
.cross span {
  position: absolute; left: 50%; top: 50%;
  transform: translate(20px, -50%);
  max-width: 40ch;
  padding: 3px 7px;
  background: var(--panel);
  border: 2px solid var(--gold);
  font: 400 9.5px/1.4 var(--display); letter-spacing: .06em;
  color: var(--gold);
  white-space: nowrap;
  opacity: 0;
  transition: opacity .12s ease;
}
.cross.on span { opacity: 1; }

/* ---------------------------------------------------------------- the hint */
.hud-bl { position: absolute; left: var(--pad); bottom: max(14px, env(safe-area-inset-bottom)); }
.hint {
  margin: 0;
  padding: 8px 11px;
  max-width: 46ch;
  background: var(--panel);
  border: 2px solid var(--edge);
  color: var(--sky);
  font-size: 12px;
  transition: opacity .8s ease;
}
.hint b { color: var(--gold); font-weight: 400; }
.hint.gone { opacity: 0; }
.hint-m { display: none; }

/* ------------------------------------------------------ the mobile stick */
.stick {
  position: relative;
  width: 116px; height: 116px;
  margin-top: 10px;
  border-radius: 50%;
  border: 2px solid var(--edge);
  background: rgba(16, 16, 24, .55);
  touch-action: none;
}
.stick i {
  position: absolute; left: 50%; top: 50%;
  width: 46px; height: 46px; margin: -23px 0 0 -23px;
  border-radius: 50%;
  background: var(--sky); border: 2px solid var(--ink);
  opacity: .85;
}

/* ============================================================ the mint HUD
   Docked bottom-right with a 24 px margin and capped at 60vh, its body the only
   thing that scrolls. It used to be laid out from the bottom with no ceiling,
   which ran the footnote off the bottom of a 1440 x 900 window — the panel has
   to fit inside the viewport at every size the site is shot at, footnote and
   all, or the rules of the mint are only half readable. */
.mint {
  position: absolute;
  right: max(24px, env(safe-area-inset-right));
  bottom: max(24px, env(safe-area-inset-bottom));
  width: 300px;
  max-height: min(60vh, calc(100vh - 96px));
  display: flex; flex-direction: column;
  background: var(--panel);
  border: 2px solid var(--glow);
  box-shadow: 0 0 0 2px var(--ink), 0 10px 40px rgba(0, 0, 0, .55);
}
.mint-grab {
  display: flex; align-items: center; gap: 10px;
  width: 100%; flex: none;
  padding: 8px 10px;
  background: var(--glow);
  color: var(--ink);
  border: 0;
  text-align: left;
  cursor: default;
}
.mint-grab > span:first-child { font-size: 12px; letter-spacing: .12em; }
.mint-grab-n { margin-left: auto; font: 600 11.5px/1 var(--mono); }
.mint-grab i { display: none; }

.mint-body { padding: 10px; overflow: auto; overscroll-behavior: contain; }
.mint-rule {
  margin: 0 0 9px;
  font: 400 10px/1.5 var(--display);
  letter-spacing: .04em;
  color: var(--sky);
}
.mint-rule b { color: var(--gold); }
#ruleGate { color: var(--slate); }

.mint-row { display: flex; align-items: stretch; gap: 9px; }
.qty { display: flex; align-items: center; border: 2px solid var(--edge); }
.qbtn {
  width: 30px; height: 36px;
  background: transparent; border: 0; color: var(--sky);
  font-size: 17px; line-height: 1;
}
.qbtn:hover:not(:disabled) { background: rgba(90, 208, 255, .16); color: var(--glow); }
.qbtn:disabled { color: #3d4257; cursor: not-allowed; }
.qty-n { min-width: 30px; text-align: center; font-size: 18px; color: var(--marble); }

.cost { flex: 1; display: flex; flex-direction: column; justify-content: center; text-align: right; }
.cost-k { font: 400 8.5px/1 var(--display); letter-spacing: .12em; color: var(--slate); }
.cost-v { font-size: 14px; color: var(--gold); margin-top: 3px; word-break: break-all; }
.cost-usd { font: 500 9.5px/1.2 var(--mono); color: var(--slate); }

/* --------------------------------------------------------------- the gate */
.gate {
  margin-top: 9px; padding: 8px;
  border: 2px solid var(--gold);
  background: rgba(255, 210, 74, .08);
}
.gate-say { margin: 0; font-size: 12px; color: var(--gold); }
.gate-say b { font-family: var(--mono); font-weight: 600; }

.btn {
  display: block; width: 100%;
  padding: 10px 8px;
  border: 2px solid var(--ink);
  font-family: var(--display); font-size: 11.5px; letter-spacing: .07em;
  text-align: center;
}
.btn-buy { margin-top: 7px; background: var(--gold); color: var(--ink); }
.btn-buy:hover { background: #ffe08a; }
.btn-mint {
  margin-top: 10px;
  background: var(--glow-2); color: var(--ink);
  box-shadow: 0 3px 0 #178a56;
}
.btn-mint:hover:not(:disabled) { background: #6bffbb; }
.btn-mint:active:not(:disabled) { transform: translateY(2px); box-shadow: 0 1px 0 #178a56; }
.btn-mint:disabled { background: #2c3346; color: #6b7590; box-shadow: none; cursor: not-allowed; }

.status-line { margin: 9px 0 0; font-size: 11.5px; line-height: 1.4; color: var(--sky); min-height: 2.8em; }
.status-line.ok { color: var(--glow-2); font-weight: 600; }
.status-line.err { color: var(--err); font-weight: 600; }
.txline { margin: 6px 0 0; font: 500 10.5px/1.4 var(--mono); color: var(--slate); word-break: break-all; }
.txline a { color: var(--glow); }
.mint-foot {
  margin: 8px 0 0; padding-top: 7px; border-top: 2px solid var(--edge);
  font: 400 9px/1.4 var(--display); letter-spacing: .05em; color: var(--slate);
}

/* ======================================================= the object card */
.card {
  position: absolute;
  left: var(--pad);
  top: 50%; transform: translateY(-50%);
  width: 320px; max-height: 74vh; overflow: auto;
  padding: 14px;
  background: var(--panel);
  border: 2px solid var(--gold);
  box-shadow: 0 0 0 2px var(--ink), 0 10px 40px rgba(0, 0, 0, .55);
}
.card-x {
  position: absolute; top: 6px; right: 8px;
  background: none; border: 0; color: var(--slate); font-size: 21px; line-height: 1; padding: 2px 5px;
}
.card-x:hover { color: var(--gold); }
.card-k { margin: 0; font-size: 10px; letter-spacing: .16em; color: var(--slate); }
.card-k2 { margin-top: 14px; padding-top: 10px; border-top: 2px solid var(--edge); }
.card-v { margin: 5px 0 8px; font-size: 20px; color: var(--gold); }
.card-say { margin: 0 0 10px; font-size: 13px; line-height: 1.5; color: var(--sky); }
.card-share { margin: 0; font-size: 12.5px; color: var(--marble); }
.card-share b { color: var(--glow); font-family: var(--mono); }
.card-list { margin: 8px 0 0; padding: 0; list-style: none; }
.card-list li {
  display: grid; grid-template-columns: 1fr auto auto; gap: 8px; align-items: baseline;
  padding: 4px 0; border-bottom: 1px solid rgba(58, 78, 106, .5);
  font-size: 12px; color: var(--sky);
}
.card-list li.on { color: var(--gold); font-weight: 700; }
.card-list li em { font-style: normal; }
.card-list li b { font: 500 11.5px/1 var(--mono); color: var(--marble); }
.card-list li span { font: 500 11px/1 var(--mono); color: var(--slate); min-width: 46px; text-align: right; }
.card-list li.on b, .card-list li.on span { color: var(--gold); }

/* ==================================================== the traits drawer */
.traits {
  position: absolute; left: var(--pad); top: var(--pad);
  width: 340px; max-height: 78vh; overflow: auto;
  padding: 14px;
  background: var(--panel);
  border: 2px solid var(--glow);
  box-shadow: 0 0 0 2px var(--ink), 0 10px 40px rgba(0, 0, 0, .55);
}
.traits-head { display: flex; align-items: center; }
.traits-head p { margin: 0; font-size: 13px; color: var(--gold); }
.traits-head .card-x { position: static; margin-left: auto; }
.traits-lede { margin: 8px 0 12px; font-size: 12.5px; line-height: 1.5; color: var(--sky); }
.traits-lede b { color: var(--gold); }
.traits-list { margin: 0; padding: 0; list-style: none; }
.traits-list li {
  display: grid; grid-template-columns: 86px 1fr auto; gap: 8px; align-items: baseline;
  padding: 5px 0; border-bottom: 1px solid rgba(58, 78, 106, .5);
  font-size: 12px;
}
.traits-list li i {
  font: 400 9px/1.4 var(--display); font-style: normal; letter-spacing: .04em; color: var(--slate);
}
.traits-list li b { color: var(--marble); font-weight: 600; }
.traits-list li.none b { color: #566079; font-weight: 400; font-style: italic; }
.traits-list li span { font: 500 10.5px/1 var(--mono); color: var(--glow); }
.traits-list li:hover { background: rgba(90, 208, 255, .08); }
.traits-foot { margin: 12px 0 0; font: 400 9.5px/1.5 var(--display); color: var(--slate); }

.noscript {
  position: fixed; inset: auto 0 0 0; margin: 0; padding: 14px;
  background: var(--shell); color: var(--sky); font-size: 13px; z-index: 9;
}

/* =================================================================== phone */
@media (max-width: 720px), (pointer: coarse) and (max-width: 900px) {
  .hint-d { display: none; }
  .hint-m { display: inline; }

  .hud-tl { max-width: 62vw; }
  .chip-v { font-size: 10px; }
  .chip-count b { font-size: 13px; }

  /* On a phone the mint is a bottom sheet, and it starts SHUT: a 56 px bar that
     says what it is and what the count is, so the room is the first thing you
     see rather than a wall of numbers. Tapping the bar opens it. It is opaque —
     a translucent one lets the room read straight through the figures. */
  .mint {
    left: 0; right: 0; bottom: 0;
    width: auto;
    background: #0c0c14;
    border-width: 3px 0 0;
    box-shadow: 0 -8px 30px rgba(0, 0, 0, .6);
    max-height: 62dvh;
  }
  .mint-grab { cursor: pointer; height: 56px; padding: 0 14px; font-size: 13px; }
  .mint-grab > span:first-child { font-size: 14px; }
  .mint-grab-n { font-size: 13px; }
  .mint-grab-n::before { content: "· "; }
  .mint-grab i {
    display: block; width: 0; height: 0; flex: none;
    border: 7px solid transparent; border-bottom-color: var(--ink);
    transition: transform .18s;
  }
  /* shut is the resting state, so the caret points UP ("open me"); it flips
     down once the sheet is open */
  .mint:not(.shut) .mint-grab i { transform: rotate(180deg); }
  .mint-body { padding: 10px 14px calc(10px + env(safe-area-inset-bottom)); }
  .mint.shut .mint-body { display: none; }
  .status-line { min-height: 0; margin-top: 8px; font-size: 12px; }
  .mint-rule { margin-bottom: 8px; }
  .mint-foot { display: none; }
  .btn-mint { margin-top: 9px; }
  .btn { font-size: 12.5px; padding: 12px 10px; }

  /* the crosshair label would cover half a phone screen: the crosshair alone
     still says "this is clickable" */
  .cross span { display: none; }

  /* the hint and the walking stick ride on top of the sheet — main.js keeps
     --sheet up to date with its real height, open or shut */
  .hud-bl { bottom: calc(env(safe-area-inset-bottom) + var(--sheet, 180px) + 10px); }
  .hint { font-size: 11px; padding: 6px 9px; max-width: 30ch; }

  .card, .traits {
    left: 0; right: 0; top: auto; bottom: 0; transform: none;
    width: auto; max-height: 70dvh;
    background: #0c0c14;
    border-width: 3px 0 0;
    padding-bottom: calc(14px + env(safe-area-inset-bottom));
    z-index: 6;
  }
  .flat { padding: 68px 8px 200px; }
}

@media (max-width: 420px) {
  .hud-links { display: none; }
  .chip-net { display: none; }
  .hud-tr { flex-direction: row; align-items: center; gap: 6px; }
  .hud-tr .chip { margin-bottom: 0; }
  .brand { font-size: 15px; }
  .chip-info .chip-v { display: none; }   /* the ⓘ alone, to leave the count room */
  .chip-info { padding: 6px 7px; }
}

/* the still frame is the whole point of the reduced-motion path: nothing here
   is allowed to animate */
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .001ms !important; animation-iteration-count: 1 !important; transition-duration: .001ms !important; }
}
