*, *::before, *::after { box-sizing: border-box; }

:root {
  --paper: #f0e9dc;
  --paper-shade: #e8dfcd;
  --ink: #1a1714;
  --ink-soft: rgba(26, 23, 20, .66);
  --rule: rgba(26, 23, 20, .3);
  --rule-soft: rgba(26, 23, 20, .14);
  --accent: #b4402a;
  --accent-dark: #8f3220;

  /* Вторая печатная краска. Светлота и насыщенность одинаковы у всех семи,
     меняется только тон — ни одна кость не выделяется громкостью.
     Дуга 95°–335° держится в холодной части: тёплое красное отдано киновари,
     которая значит крит, и ни одна кость не должна быть на неё похожа.
     Тона розданы вперемешку, а не по порядку: у d8, d10 и d12 похожие силуэты,
     и им нужны далёкие друг от друга краски. */
  --ink-d4: oklch(54% 0.115 95);
  --ink-d6: oklch(54% 0.115 215);
  --ink-d8: oklch(54% 0.115 335);
  --ink-d10: oklch(54% 0.115 135);
  --ink-d12: oklch(54% 0.115 255);
  --ink-d20: oklch(54% 0.115 175);
  --ink-d100: oklch(54% 0.115 295);

  --t-micro: 12px;
  --t-meta: 13px;
  --t-small: 15px;
  --t-base: 18px;
  --t-med: 22px;
  --t-word: 28px;
  --t-display: clamp(68px, 9vw, 116px);

  --s1: 4px;
  --s2: 8px;
  --s3: 12px;
  --s4: 16px;
  --s5: 20px;
  --s6: 24px;
  --s7: 32px;
  --s8: 40px;
  --s9: 56px;

  --die: 92px;
  --journal-w: 46px;
  --serif: "EB Garamond", Georgia, serif;
  --caps: "Alegreya SC", "EB Garamond", Georgia, serif;
}

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--serif);
  font-size: var(--t-base);
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

.sprite { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.label {
  margin: 0;
  font-family: var(--caps);
  font-size: var(--t-micro);
  font-weight: 500;
  letter-spacing: .16em;
  text-transform: lowercase;
  color: var(--ink-soft);
}

.i-line {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linejoin: round;
  stroke-linecap: round;
}

.icon-btn {
  display: grid;
  place-items: center;
  flex: none;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink-soft);
  cursor: pointer;
  transition: color .15s linear;
}

.icon-btn:hover { color: var(--accent); }
.icon-btn svg { width: 22px; height: 22px; }
.icon-btn[aria-pressed="true"] .i-off { display: none; }
.icon-btn[aria-pressed="false"] .i-on { display: none; }

#colorToggle[aria-pressed="true"] .i-c1 { stroke: var(--ink-d4); }
#colorToggle[aria-pressed="true"] .i-c2 { stroke: var(--ink-d10); }
#colorToggle[aria-pressed="true"] .i-c3 { stroke: var(--ink-d20); }

.link-btn {
  margin: 0;
  padding: var(--s1) 0;
  border: 0;
  background: none;
  font-family: var(--caps);
  font-size: var(--t-small);
  letter-spacing: .06em;
  color: var(--ink-soft);
  cursor: pointer;
  border-bottom: 1px solid transparent;
  transition: color .15s linear, border-color .15s linear;
}

.link-btn:hover:not(:disabled) { color: var(--accent); border-bottom-color: var(--accent); }
.link-btn:disabled { color: var(--ink-soft); opacity: .55; cursor: default; }
.link-btn.is-armed { color: var(--accent); border-bottom-color: var(--accent); }

.sheet {
  height: 100dvh;
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--journal-w);
  grid-template-rows: minmax(0, 1fr) auto;
  grid-template-areas:
    "table   journal"
    "console journal";
}

.sheet.journal-open { --journal-w: 300px; }

/* ---------- table ---------- */

.table {
  grid-area: table;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--s7);
  padding: var(--s7) var(--s8) var(--s6) var(--s9);
  min-height: 0;
}

.tray {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s6) var(--s5);
  min-height: var(--die);
  max-height: 100%;
  overflow-y: auto;
}

.readout {
  min-height: 152px;
  border-top: 1px solid var(--ink);
  padding-top: var(--s3);
}

.verdict-formula {
  margin: 0;
  font-family: var(--serif);
  font-size: var(--t-base);
  font-variant-numeric: lining-nums tabular-nums;
  color: var(--ink-soft);
}

.verdict-total {
  margin: 0;
  margin-left: -.045em;
  font-size: var(--t-display);
  line-height: 1.05;
  font-variant-numeric: lining-nums tabular-nums;
  letter-spacing: -.02em;
}

.readout.is-crit .verdict-total { color: var(--accent); }
.readout.is-crit .verdict-formula::after { content: " · крит"; color: var(--accent); }
.readout.is-fumble .verdict-formula::after { content: " · провал"; color: var(--accent); }

.readout.is-stale .verdict-total { color: var(--ink-soft); opacity: .55; }
.readout.is-empty .verdict-total { color: var(--ink-soft); }

/* ---------- dice ---------- */

.die {
  position: relative;
  width: var(--die);
  height: var(--die);
  flex: none;
  transform: rotate(var(--tilt, 0deg));
}

.die-shape { position: absolute; inset: 0; width: 100%; height: 100%; }

.die-shape .d-body {
  fill: var(--paper);
  stroke: var(--ink);
  stroke-width: 2.4;
  stroke-linejoin: round;
}

.die-shape .d-shade {
  stroke: var(--ink);
  stroke-width: 1.3;
  stroke-linejoin: round;
}

.die-shape .d-shade--a { fill: url(#hatchA); }
.die-shape .d-shade--b { fill: url(#hatchB); }

.die-shape .d-face {
  fill: var(--paper);
  stroke: var(--ink);
  stroke-width: 1.7;
  stroke-linejoin: round;
}

.die-shape .d-line {
  fill: none;
  stroke: var(--ink);
  stroke-width: 1.3;
  stroke-linecap: round;
}

.die-value {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  translate: 0 var(--dy, 0);
  font-family: var(--serif);
  font-weight: 500;
  font-size: calc(var(--die) * .3);
  font-variant-numeric: lining-nums tabular-nums;
  line-height: 1;
}

.die[data-len="2"] .die-value { font-size: calc(var(--die) * .27); }
.die[data-len="3"] .die-value { font-size: calc(var(--die) * .21); }
.die[data-sides="4"] .die-value { font-size: calc(var(--die) * .25); }

.die-ghost {
  position: absolute;
  right: -6px;
  bottom: -2px;
  font-size: var(--t-small);
  color: var(--ink-soft);
  text-decoration: line-through;
  font-variant-numeric: lining-nums;
}

.die.is-rolling { animation: drop var(--dur, 520ms) cubic-bezier(.3, .8, .4, 1) var(--delay, 0ms) backwards; }

@keyframes drop {
  0%   { opacity: 0; transform: translate(-16px, -38px) rotate(-24deg) scale(1.16); }
  45%  { opacity: 1; }
  100% { opacity: 1; transform: translate(0, 0) rotate(var(--tilt, 0deg)) scale(1); }
}

.die.is-landed { animation: stamp 170ms ease-out; }

@keyframes stamp {
  0% { scale: 1.08; }
  100% { scale: 1; }
}

.die.is-crit .d-body { stroke: var(--accent); stroke-width: 3.6; }
.die.is-crit .d-face { stroke: var(--accent); }
.die.is-crit .d-line { stroke: var(--accent); }
.die.is-crit .d-shade { stroke: var(--accent); }
.die.is-crit .d-shade--a { fill: url(#hatchAccentA); }
.die.is-crit .d-shade--b { fill: url(#hatchAccentB); }
.die.is-crit .die-value { color: var(--accent); }

.die.is-fumble .d-face { fill: var(--ink); }
.die.is-fumble .die-value { color: var(--paper); }

.mod-chip {
  align-self: center;
  font-size: var(--t-word);
  font-variant-numeric: lining-nums tabular-nums;
  color: var(--ink-soft);
  animation: fade 320ms linear backwards;
  animation-delay: var(--delay, 0ms);
}

@keyframes fade { from { opacity: 0; } to { opacity: 1; } }

/* ---------- console ---------- */

.console {
  grid-area: console;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--s6) var(--s9);
  padding: var(--s5) var(--s8) var(--s4) var(--s9);
  border-top: 1px solid var(--ink);
}

.picker { display: flex; flex-wrap: wrap; gap: var(--s1); margin-top: var(--s2); }

.pick {
  position: relative;
  padding: var(--s1) var(--s3) var(--s2);
  border: 0;
  background: none;
  font: inherit;
  color: var(--ink);
  cursor: pointer;
}

.pick svg { display: block; width: 46px; height: 46px; }
.pick .d-body { fill: var(--paper); stroke: var(--ink); stroke-width: 3.4; stroke-linejoin: round; }
.pick .d-shade { stroke: var(--ink); stroke-width: 1.8; stroke-linejoin: round; fill: none; }
.pick .d-shade--b { fill: url(#hatchA); }
.pick .d-face { fill: var(--paper); stroke: var(--ink); stroke-width: 2.4; stroke-linejoin: round; }
.pick .d-line { fill: none; stroke: var(--ink); stroke-width: 1.8; stroke-linecap: round; }

.pick-name {
  display: block;
  margin-top: var(--s1);
  font-family: var(--caps);
  font-size: var(--t-meta);
  letter-spacing: .1em;
  text-align: center;
  border-bottom: 1px solid transparent;
}

.pick:hover .pick-name { border-bottom-color: var(--ink); }

.pick.is-picked .d-body { stroke: var(--accent); }
.pick.is-picked .d-face { stroke: var(--accent); }
.pick.is-picked .pick-name { color: var(--accent); border-bottom-color: var(--accent); }

.pick.is-full { cursor: default; }
.pick.is-full .pick-name { border-bottom-style: dotted; }

.pick-count {
  position: absolute;
  top: 0;
  right: 0;
  font-family: var(--serif);
  font-size: var(--t-small);
  font-weight: 600;
  font-variant-numeric: lining-nums;
  color: var(--accent);
  background: var(--paper);
  padding: 0 2px;
}

.controls { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--s6) var(--s8); flex: 1; }

.control { display: flex; flex-direction: column; gap: var(--s2); }

.stepper {
  display: flex;
  align-items: stretch;
  border: 1px solid var(--ink);
  width: fit-content;
}

.stepper button {
  width: 40px;
  border: 0;
  background: none;
  font-family: var(--serif);
  font-size: var(--t-med);
  line-height: 1;
  color: var(--ink);
  cursor: pointer;
  transition: background .12s linear, color .12s linear;
}

.stepper button:hover:not(:disabled) { background: var(--ink); color: var(--paper); }
.stepper button:disabled { color: var(--ink-soft); opacity: .45; cursor: default; }

.stepper-value {
  min-width: 56px;
  padding: var(--s2) 0;
  text-align: center;
  font-size: var(--t-med);
  line-height: 1;
  font-variant-numeric: lining-nums tabular-nums;
  border-inline: 1px solid var(--ink);
}

.modes { display: flex; gap: var(--s5); }

.modes button {
  padding: var(--s2) 0;
  border: 0;
  border-bottom: 1px solid transparent;
  background: none;
  font-family: var(--serif);
  font-size: var(--t-base);
  line-height: 1;
  color: var(--ink-soft);
  cursor: pointer;
  transition: color .12s linear, border-color .12s linear;
}

.modes button:hover { color: var(--ink); }
.modes button.is-active { color: var(--accent); border-bottom-color: var(--accent); }

.actions {
  display: flex;
  align-items: center;
  gap: var(--s5);
  margin-left: auto;
  padding-top: var(--s5);
}

.roll-btn {
  padding: var(--s3) var(--s7);
  border: 1px solid var(--accent);
  background: var(--accent);
  color: var(--paper);
  font-family: var(--caps);
  font-size: var(--t-base);
  font-weight: 500;
  letter-spacing: .08em;
  line-height: 1.2;
  cursor: pointer;
  transition: background .12s linear, border-color .12s linear;
}

.roll-btn:hover:not(:disabled) { background: var(--accent-dark); border-color: var(--accent-dark); }

.roll-btn:disabled {
  background: none;
  border-color: var(--ink-soft);
  color: var(--ink-soft);
  cursor: default;
}

.footline {
  flex-basis: 100%;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--s3) var(--s5);
}

.room { margin-left: auto; }

.room-live {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--s2) var(--s4);
}

.room-live[hidden] { display: none; }

.room-status {
  font-family: var(--caps);
  font-size: var(--t-meta);
  letter-spacing: .06em;
  color: var(--ink-soft);
}

.room-status.is-warning { color: var(--accent); }

.room-field input {
  width: 12ch;
  padding: 0 0 2px;
  border: 0;
  border-bottom: 1px solid var(--rule);
  background: none;
  font-family: var(--serif);
  font-size: var(--t-small);
  color: var(--ink);
}

.room-field input:focus {
  outline: none;
  border-bottom-color: var(--accent);
}

.journal-who {
  color: var(--ink);
  margin-right: var(--s2);
}

.legend {
  margin: 0;
  font-family: var(--caps);
  font-size: var(--t-meta);
  letter-spacing: .06em;
  color: var(--ink-soft);
}

.legend kbd {
  font-family: var(--serif);
  font-size: var(--t-small);
  font-weight: 600;
  letter-spacing: 0;
  color: var(--ink);
}

/* ---------- journal ---------- */

.journal {
  grid-area: journal;
  display: flex;
  flex-direction: column;
  min-height: 0;
  border-left: 1px solid var(--ink);
  background: var(--paper-shade);
}

.journal-tab {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--s3);
  flex: 1;
  width: 100%;
  padding: var(--s5) 0;
  border: 0;
  background: none;
  font-family: var(--caps);
  font-size: var(--t-meta);
  letter-spacing: .1em;
  color: var(--ink-soft);
  cursor: pointer;
  transition: color .15s linear;
}

.journal-tab:hover { color: var(--accent); }

.journal-tab-label { writing-mode: vertical-rl; }

.journal-tab-count {
  font-family: var(--serif);
  font-size: var(--t-small);
  font-weight: 600;
  font-variant-numeric: lining-nums;
  letter-spacing: 0;
  color: var(--accent);
}

.journal-tab-count:empty { display: none; }

.chevron { width: 20px; height: 20px; flex: none; }

.journal-body { display: none; }

.journal-open .journal-tab {
  flex: none;
  flex-direction: row;
  justify-content: flex-start;
  gap: var(--s2);
  padding: var(--s6) var(--s6) var(--s2);
}

.journal-open .journal-tab-label { writing-mode: horizontal-tb; }
.journal-open .journal-tab-count { margin-left: auto; }
.journal-open .chevron { rotate: 180deg; }

.journal-open .journal-body {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  padding: 0 var(--s6) var(--s6);
}

.journal-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s3);
  padding-bottom: var(--s2);
  border-bottom: 1px solid var(--rule);
}

.journal-list {
  margin: 0;
  padding: 0;
  list-style: none;
  overflow-y: auto;
  flex: 1;
  min-height: 0;
}

.journal-list:empty { flex: 0; }

.journal-item {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: baseline;
  gap: var(--s3);
  width: 100%;
  padding: var(--s2) 0;
  border: 0;
  border-bottom: 1px solid var(--rule-soft);
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  animation: fade 240ms linear;
}

.journal-item:hover { background: rgba(26, 23, 20, .05); }

.journal-time {
  font-size: var(--t-meta);
  color: var(--ink-soft);
  font-variant-numeric: lining-nums tabular-nums;
}

.journal-formula {
  font-size: var(--t-small);
  color: var(--ink-soft);
  font-variant-numeric: lining-nums tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.journal-total {
  font-size: var(--t-med);
  font-variant-numeric: lining-nums tabular-nums;
}

.journal-item.is-crit .journal-total { color: var(--accent); }
.journal-item.is-fumble .journal-total { text-decoration: line-through; }

.journal-note {
  margin: var(--s3) 0 0;
  font-size: var(--t-small);
  color: var(--ink-soft);
}

.journal-note[hidden] { display: none; }

/* ---------- цветной прогон ---------- */

.die[data-sides="4"],   .pick[data-sides="4"]   { --die-ink: var(--ink-d4); }
.die[data-sides="6"],   .pick[data-sides="6"]   { --die-ink: var(--ink-d6); }
.die[data-sides="8"],   .pick[data-sides="8"]   { --die-ink: var(--ink-d8); }
.die[data-sides="10"],  .pick[data-sides="10"]  { --die-ink: var(--ink-d10); }
.die[data-sides="12"],  .pick[data-sides="12"]  { --die-ink: var(--ink-d12); }
.die[data-sides="20"],  .pick[data-sides="20"]  { --die-ink: var(--ink-d20); }
.die[data-sides="100"], .pick[data-sides="100"] { --die-ink: var(--ink-d100); }

/* Кость набирается одной краской: контур, рёбра и грани. Цифра остаётся чернилами.
   Штриховка в цветном режиме заменяется плоской заливкой — два тона вместо гравюры,
   иначе чёрный штрих под цветным контуром читается как грязь. */

.is-colored .die:not(.is-crit):not(.is-fumble) .d-body,
.is-colored .die:not(.is-crit):not(.is-fumble) .d-line,
.is-colored .die:not(.is-crit):not(.is-fumble) .d-shade,
.is-colored .die:not(.is-crit):not(.is-fumble) .d-face,
.is-colored .pick .d-body,
.is-colored .pick .d-line,
.is-colored .pick .d-shade,
.is-colored .pick .d-face { stroke: var(--die-ink); }

.is-colored .die:not(.is-crit):not(.is-fumble) .d-shade--a,
.is-colored .pick .d-shade--a { fill: color-mix(in oklab, var(--die-ink) 20%, var(--paper)); }

.is-colored .die:not(.is-crit):not(.is-fumble) .d-shade--b,
.is-colored .pick .d-shade--b { fill: color-mix(in oklab, var(--die-ink) 42%, var(--paper)); }

.is-colored .pick.is-picked .d-face { fill: color-mix(in oklab, var(--die-ink) 8%, var(--paper)); }
.is-colored .pick.is-picked .d-body { stroke-width: 4.6; }

.is-colored .pick.is-picked .pick-name { color: var(--die-ink); border-bottom-color: var(--die-ink); }
.is-colored .pick:hover .pick-name { border-bottom-color: var(--die-ink); }
.is-colored .pick-count { color: var(--die-ink); }

:where(button):focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* ---------- adaptive ---------- */

@media (max-width: 1340px) {
  :root { --die: 84px; }
  .table { padding: var(--s6) var(--s7) var(--s5) var(--s8); gap: var(--s6); }
  .readout { min-height: 138px; }
  .console { padding: var(--s4) var(--s7) var(--s3) var(--s8); gap: var(--s5) var(--s7); }
  .controls { gap: var(--s5) var(--s7); }
  .sheet.journal-open { --journal-w: 268px; }
}

@media (max-width: 940px) {
  :root { --die: 72px; --journal-w: auto; }

  body { font-size: 17px; }

  .sheet {
    height: auto;
    min-height: 100dvh;
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto;
    grid-template-areas: "table" "console" "journal";
  }

  .sheet.journal-open { --journal-w: auto; }

  .table { padding: var(--s6) var(--s5); gap: var(--s5); }
  .readout { min-height: 118px; }
  .tray { max-height: none; overflow-y: visible; }

  .console { padding: var(--s5); gap: var(--s5) var(--s7); }
  .actions { width: 100%; margin-left: 0; padding-top: var(--s2); }
  .roll-btn { flex: 1; }

  .journal { border-left: 0; border-top: 1px solid var(--ink); }

  .journal-tab {
    flex: none;
    flex-direction: row;
    justify-content: flex-start;
    gap: var(--s2);
    padding: var(--s4) var(--s5);
  }

  .journal-tab-label { writing-mode: horizontal-tb; }
  .journal-tab-count { margin-left: auto; }
  .journal-open .journal-tab { padding: var(--s4) var(--s5) var(--s2); }
  .journal-open .journal-body { padding: 0 var(--s5) var(--s5); }
  .journal-list { max-height: 320px; }
}

@media (prefers-reduced-motion: reduce) {
  .die.is-rolling { animation: fade 200ms linear var(--delay, 0ms) backwards; }
  .die.is-landed { animation: none; }
}
