/* The Build view (village_sheet.rs, `build_view`): the village's works on the book (ui.css, "The
   book"), a game's build screen drawn on paper. The verso holds the village's coins, every
   building as a tile of the roster (its picture standing on the page, its name, its rank; a
   ghost of it while its plot is empty; a seal while the village can pay for its next step) and
   the chosen one's way as a tree. The recto shows the chosen one large, what the coins buy
   standing as the hero (at a fork every path side by side), what the step makes of it, now to
   after, and the call to action with the price on it. Coins and gains are gold ink, what acts
   and what is picked the accent on paper. */
.build-body {
  .page-body { display: flex; flex-direction: column; }
  .art { display: block; flex: none; }
  /* Ranks as diamonds: reached in gold ink, the one to raise next ringed in the accent. */
  .pips {
    display: inline-flex; align-items: center; gap: 5px;
    i { width: 8px; height: 8px; rotate: 45deg; border: 1px solid var(--gold-ink); }
    i.on { background: var(--gold-ink); }
    i.next { border-color: var(--accent-on-paper); border-width: 1.5px; animation: pip-next 1.8s ease-in-out infinite; }
  }
  /* A building's picture stands on the page, a wash of ink under its foot. */
  :is(.lot-pic, .node-pic, .hero, .path-pic) { position: relative; display: block;
    &::before { content: ""; position: absolute; left: 14%; right: 14%; bottom: 4%; height: 18%; border-radius: 50%;
      background: radial-gradient(closest-side, var(--sumi-shade), transparent); }
    img { position: absolute; inset: 0; z-index: 1; display: block; width: 100%; height: 100%; object-fit: contain;
      filter: drop-shadow(0 4px 3px var(--sumi-shade)); transition: scale 0.25s var(--ease-spring), filter 0.2s; }
  }
}
@keyframes pip-next { 50% { background: var(--accent-on-paper-wash); } }

/* ---- The verso: the coins, the roster, the way ------------------------------------------------- */
.build-body {
  .build-head { flex: none; display: flex; align-items: flex-start; gap: 20px; margin-bottom: 14px;
    .spread-head { margin: 0; }
  }
  .purse {
    display: grid; grid-template-columns: auto auto; align-items: center; gap: 6px 10px; margin-left: auto; padding-top: 2px;
    .art.coin { width: 28px; height: 28px; filter: drop-shadow(0 1px 1px var(--sumi-shade)); }
    b { font: 500 32px/1 var(--face); color: var(--gold-ink); font-variant-numeric: tabular-nums; }
    span { grid-column: 1 / -1; justify-self: end; font: 600 10px/1 var(--face); letter-spacing: 0.22em; text-transform: uppercase;
      color: var(--sumi-faint); }
  }
  /* The roster: every building's tile, three abreast. */
  .roster { flex: none; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px 12px; padding: 4px 0 8px; }
  .lot { position: relative; display: flex; flex-direction: column; align-items: center; gap: 3px; min-width: 0; padding: 6px 4px 10px;
    border: 0; border-radius: 2px; background: none; cursor: pointer; text-align: center; color: var(--sumi);
    -webkit-tap-highlight-color: transparent; transition: background 0.15s, translate 0.2s var(--ease-spring), scale 0.2s var(--ease-spring);
    &:hover { background: var(--sumi-wash); }
    &:hover .lot-pic img { scale: 1.06; }
    &:active { scale: 0.97; transition-duration: 0.06s; }
    &:focus-visible { outline: 1px solid var(--accent-on-paper); outline-offset: 2px; }
    &.on { background: linear-gradient(180deg, transparent, var(--accent-on-paper-wash)); box-shadow: inset 0 -3px 0 var(--accent-on-paper); }
  }
  .lot-pic { width: 100%; aspect-ratio: 16 / 10; }
  .lot-name { max-width: 100%; margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font: 600 16px/1.2 var(--face); }
  .lot-state {
    display: flex; align-items: center; justify-content: center; min-height: 14px;
    small { font: 600 9.5px/1 var(--face); letter-spacing: 0.2em; text-transform: uppercase; color: var(--sumi-faint); }
  }
  /* Not built: a pale ghost of what may stand there. */
  :is(.lot.unbuilt .lot-pic, .node.later .node-pic) img { filter: grayscale(1) opacity(0.32); }
  .lot.unbuilt .lot-name { color: var(--sumi-soft); font-weight: 500; }
  .lot.on .lot-name { color: var(--accent-on-paper); }
  /* The seal: the village can pay for this building's next step. */
  .lot .up { position: absolute; top: 4px; right: 6px; z-index: 2; width: 20px; height: 20px; rotate: 45deg; pointer-events: none;
    background: var(--seal, var(--accent-on-paper)) center / 100% 100%; filter: drop-shadow(0 1px 1px var(--sumi-shade));
    animation: lot-up 2.4s ease-in-out infinite; }

  /* The chosen one's way: its base, then each branch under one another, joined by ink. */
  .way { flex: none; margin-top: 14px; padding-top: 18px; border-top: 1px solid var(--sumi-line);
    > h3 { margin-bottom: 10px; font: 600 10.5px/1 var(--face); letter-spacing: 0.22em; text-transform: uppercase; color: var(--sumi-faint); }
  }
  .tree {
    display: flex; align-items: center; min-width: 0;
    .node { display: flex; align-items: center; gap: 10px; min-width: 0; }
    .node-pic { flex: none; width: 92px; height: 62px; }
    .node-name {
      display: flex; flex-direction: column; align-items: flex-start; gap: 5px; min-width: 0;
      b { font: 600 17px/1.15 var(--face); white-space: nowrap; color: var(--sumi); }
    }
    .base {
      flex: none; position: relative; padding-right: 34px;
      &::after { content: ""; position: absolute; right: 0; top: 50%; width: 26px; border-top: 1.5px solid var(--sumi-line); }
    }
    .branches {
      margin: 0; padding: 0; list-style: none; min-width: 0;
      > li { position: relative; padding: 4px 0 4px 24px; }
      > li::before { content: ""; position: absolute; left: 0; top: 50%; width: 18px; border-top: 1.5px solid var(--sumi-line); }
      > li::after { content: ""; position: absolute; left: 0; top: 0; bottom: 0; border-left: 1.5px solid var(--sumi-line); }
      > li:first-child::after { top: 50%; }
      > li:last-child::after { bottom: 50%; }
      > li:only-child::after { display: none; }
    }
    .done::after, .taken::before { border-color: var(--gold-ink); }
    .next .node-name b, .open.sel b { color: var(--accent-on-paper); }
    .open .node-pic::before { background: radial-gradient(closest-side, var(--accent-on-paper-wash), transparent); }
    .open.sel::before { border-top-color: var(--accent-on-paper); }
    :is(.later, .closed) .node-name { opacity: 0.6; }
    .closed {
      .node-pic img { filter: grayscale(1) opacity(0.4); }
      b { text-decoration: line-through; text-decoration-color: var(--vermilion-ink); }
      &::before { border-top-style: dashed; }
    }
  }
}
@keyframes lot-up { 50% { scale: 1.12; } }

/* ---- The recto: the chosen one large, the deal --------------------------------------------------- */
.build-body {
  .showcase { flex: 1 0 auto; display: flex; flex-direction: column; min-width: 0; }
  .build-stage { flex: none; display: grid; grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr); align-items: center; gap: 10px 22px; }
  .stage-title { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; min-width: 0; }
  .tag { font: 700 10.5px/1 var(--face); letter-spacing: 0.26em; text-transform: uppercase; color: var(--accent-on-paper); }
  .build-stage h3 {
    display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; font: 600 40px/1.05 var(--face);
    .pips i { width: 10px; height: 10px; }
  }
  .blurb { max-width: 32ch; margin: 0; font: italic 400 15px/1.45 var(--face); color: var(--sumi-faint); }
  .hero { height: clamp(150px, 30vh, 260px); }
  .build-stage:hover .hero img { scale: 1.02; }
  .showcase.complete .hero img { filter: drop-shadow(0 4px 3px var(--sumi-shade)) drop-shadow(0 0 14px var(--gold-ink)); }
  /* A fork: every path standing side by side under the title. */
  .showcase.fork .build-stage { grid-template-columns: minmax(0, 1fr); justify-items: center; gap: 14px; }
  .showcase.fork .stage-title { align-items: center; text-align: center; gap: 6px; }
  .showcase.fork h3 { font-size: 30px; }
  .paths { display: flex; align-items: flex-start; justify-content: center; width: 100%; }
  .path { position: relative; flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: 7px;
    padding: 4px 8px 10px; border: 0; border-radius: 2px; background: none; cursor: pointer; color: var(--sumi); -webkit-tap-highlight-color: transparent;
    transition: opacity 0.2s, background 0.15s, translate 0.2s var(--ease-spring), scale 0.2s var(--ease-spring);
    .full { font: italic 400 13px/1.3 var(--face); color: var(--sumi-faint); }
    &:hover { background: var(--sumi-wash); }
    &:hover .path-pic img { scale: 1.04; }
    &:active { scale: 0.975; transition-duration: 0.06s; }
    &:focus-visible { outline: 1px solid var(--accent-on-paper); outline-offset: 2px; }
    &.sel .path-pic::before { background: radial-gradient(closest-side, var(--accent-on-paper-wash), transparent);
      box-shadow: 0 0 0 1.5px var(--accent-on-paper); }
    &.sel .path-name b { color: var(--accent-on-paper); }
  }
  .path-pic { width: 100%; height: clamp(110px, 20vh, 180px); }
  .path-name { display: flex; align-items: center; gap: 10px;
    b { font: 600 22px/1.1 var(--face); transition: color 0.15s; }
  }
  .path-deal { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 6px 10px; }
  .paths {
    &:has(.sel) .path:not(.sel) { opacity: 0.5; }
    &:has(.sel) .path:not(.sel) .path-pic img { filter: grayscale(0.8) drop-shadow(0 4px 3px var(--sumi-shade)); }
    .or { flex: none; align-self: center; width: 36px; text-align: center; font: italic 500 22px/1 var(--face); color: var(--sumi-faint); }
  }
  /* What a step adds, as chips with a gold rune; a price in gold ink, vermilion when the village is short. */
  .give {
    display: inline-flex; align-items: center; gap: 6px; padding: 4px 9px 4px 7px; font: 400 14px/1 var(--face);
    color: var(--sumi-soft); box-shadow: inset 0 0 0 1px var(--sumi-line);
    .rune { width: 15px; height: 15px; color: var(--gold-ink); }
    b { font-weight: 700; color: var(--sumi); }
  }
  .price {
    display: inline-flex; align-items: center; gap: 6px;
    .art.coin { width: 20px; height: 20px; filter: drop-shadow(0 1px 1px var(--sumi-shade)); }
    b { font: 600 19px/1 var(--face); color: var(--gold-ink); font-variant-numeric: tabular-nums; }
    &.short b { color: var(--vermilion-ink); }
  }

  /* What a step asks of the storehouse: a chip by its price (the journey's rune: from how far),
     vermilion when the storehouse holds too little; in full in the deal, against what it holds. */
  .needs {
    display: inline-flex; align-items: center; gap: 6px; padding: 4px 9px 4px 7px; font: 400 14px/1 var(--face);
    color: var(--sumi-soft); box-shadow: inset 0 0 0 1px var(--sumi-line);
    .rune { width: 15px; height: 15px; color: var(--gold-ink); }
    b { font-weight: 700; color: var(--sumi); }
    &.short { box-shadow: inset 0 0 0 1px var(--vermilion-ink); }
    &.short b, &.short .rune { color: var(--vermilion-ink); }
  }
  .needs-full { display: grid; gap: 4px;
    p { margin: 0; font: 400 15px/1.35 var(--face); color: var(--sumi-soft); }
    b { font-weight: 600; color: var(--sumi); font-variant-numeric: tabular-nums; }
    .held { font-size: 14px; color: var(--sumi-faint); }
    &.short .held b { color: var(--vermilion-ink); }
  }

  /* The deal: what the step makes of the building, now to after, over the call to action. */
  .deal { flex: none; display: flex; flex-direction: column; gap: 18px; margin-top: auto; padding-top: 18px; border-top: 1px solid var(--sumi-line);
    :is(.note, .problem) { max-width: 440px; margin: 0; }
  }
  .gains { display: grid; gap: 10px; margin: 0; padding: 0; list-style: none; }
  .gain { display: grid; grid-template-columns: 22px 110px auto; justify-content: start; align-items: center; gap: 12px;
    font: 400 15px/1.2 var(--face); color: var(--sumi-soft);
    .rune { width: 19px; height: 19px; color: var(--gold-ink); }
    .was { font: 400 22px/1 var(--face); color: var(--sumi-faint); font-variant-numeric: tabular-nums; text-align: right; }
    .into:not(:empty), &.up .into { position: relative; height: 12px; }
    &.up .into::before { content: ""; position: absolute; left: 0; right: 5px; top: 5px; height: 1.5px; background: var(--sumi-faint); }
    &.up .into::after { content: ""; position: absolute; right: 1px; top: 2px; width: 7px; height: 7px; rotate: 45deg;
      border: solid var(--sumi-faint); border-width: 1.5px 1.5px 0 0; }
    b { font: 500 30px/1 var(--face); color: var(--sumi); font-variant-numeric: tabular-nums; }
    &.up b { color: var(--gold-ink); }
    em { justify-self: start; padding: 3px 6px; font: 700 12.5px/1 var(--face); font-style: normal; color: var(--gold-ink);
      box-shadow: inset 0 0 0 1px var(--gold-ink);
      &:empty { visibility: hidden; }
    }
  }
  .gains.step .gain { grid-template-columns: 22px 110px 40px 22px auto auto; }
  .actions { display: flex; flex-direction: column; align-items: flex-start; gap: 12px; }
  .cta.buy { height: 54px; padding: 0 24px 0 calc(26px + 0.24em); font-size: 14.5px;
    .cost { display: inline-flex; align-items: center; gap: 7px; margin-left: 18px; padding-left: 16px;
      border-left: 1px solid var(--on-accent-faint); font: 800 19px/1 var(--face); letter-spacing: 0; font-variant-numeric: tabular-nums; }
    .cost .art.coin { width: 21px; height: 21px; filter: drop-shadow(0 1px 1px var(--accent-shadow)); }
    &:not(:disabled)::before { animation: raise-beckon 2.4s ease-in-out infinite; }
  }
}
@media (max-height: 800px) {
  .build-body {
    .roster { gap: 4px 8px; }
    .lot { padding-block: 2px 6px; }
    .lot-pic { aspect-ratio: 2 / 1; }
    .build-stage { gap: 6px 18px; }
    .build-stage h3 { font-size: 30px; }
    .showcase.fork h3 { font-size: 26px; }
    .hero { height: 130px; }
    .path { gap: 4px; padding-bottom: 4px; }
    .path-pic { height: 92px; }
    .path-name b { font-size: 19px; }
    .path .full { font-size: 12px; }
    .deal { gap: 10px; padding-top: 10px; }
    .gain b { font-size: 24px; }
    .cta.buy { height: 46px; }
  }
}
@media (prefers-reduced-motion: reduce) { .build-body :is(.lot .up, .pips i.next) { animation: none; } }
