/* Dwarven Hold base styles on the Deep Ledger tokens (hold-theme.css, loaded first). Workspace chrome: workspace.css. */

/* Old variable names, kept until workspace.css is rewritten on the tokens. --gold and --text are theme tokens already. */
:root { --bg: var(--ink-1); --panel: var(--ink-0); --border: var(--gold-dark); --muted: var(--text-2); }
/* Pages without a map: in the parchment theme the void behind the panels is chrome too. */
[data-theme="light"] body { background: var(--ink-2); }

* { box-sizing: border-box; }
body { margin: 0; }
a { text-decoration: none; }
h1, h2, h3 { font-family: inherit; font-weight: 500; letter-spacing: 0; line-height: 1.25; }
h1 { margin: var(--s-2) 0 var(--s-6); font-size: var(--fs-hero); }
h2 { margin: var(--s-3) 0 var(--s-4); font-size: var(--fs-xl); }
h3 { margin: var(--s-6) 0 var(--s-4); font-size: var(--fs-lg); }
p { line-height: 1.45; }
th { font-weight: 500; }
.muted { color: var(--text-2); }
.small { font-size: var(--fs-xs); }
.eyebrow { margin: 0 0 var(--s-4); color: var(--gold); font-size: var(--fs-xs); letter-spacing: .08em; text-transform: uppercase; }
hr { border: 0; border-top: 1px solid var(--gold-dark); margin: var(--s-8) 0; }

/* ---- framed panels (.dh-panel look) ---- */
.app-header, .app-footer, .page-head, .login-card, .hold-card, .notice, .preview-panel, #blazor-error-ui {
  background: var(--ink-0); border: var(--frame) solid var(--gold);
  box-shadow: 0 0 0 1px #000, inset 0 0 0 2px var(--ink-0), inset 0 0 0 3px var(--gold-dark); }

/* ---- page frame ---- */
.app-header { min-height: 56px; display: flex; gap: var(--s-8); align-items: center; padding: var(--s-3) var(--s-7); }
.brand { color: var(--text); font-size: var(--fs-lg); letter-spacing: .08em; white-space: nowrap; }
.brand-mark { color: var(--gold); margin-right: var(--s-4); }
.brand-subtitle { flex: 1; color: var(--text-2); font-size: var(--fs-sm); }
.session { display: flex; align-items: center; gap: var(--s-6); font-size: var(--fs-sm); }
.app-main { max-width: 1600px; margin: auto; padding: var(--s-8); min-height: calc(100vh - 140px); }
.app-footer { display: flex; justify-content: space-between; gap: var(--s-6); padding: var(--s-4) var(--s-7); color: var(--text-2); font-size: var(--fs-xs); letter-spacing: .08em; }
.app-loading { position: fixed; inset: 0; display: grid; place-items: center; margin: 0; color: var(--gold); font-size: var(--fs-lg); }
.empty-state { padding: var(--s-8) 0; }

/* ---- controls: every plain button is the neutral .dh-btn (.secondary included); colour comes from meaning, not rank.
   Zero specificity and skipped for .dh-* buttons, so component classes (.text-button, .dh-row, .dh-tab…) style themselves. ---- */
:where(button:not([class*="dh-"])), .button { display: inline-block; min-height: 24px; padding: 1px 10px; background: var(--control); color: var(--text);
  border: 1px solid var(--control-edge); border-radius: 0; box-shadow: inset 1px 1px 0 var(--control-hi); font: inherit; text-shadow: inherit; cursor: pointer; }
:where(button:not([class*="dh-"])):hover, .button:hover { border-color: var(--gold); color: var(--text); }
:where(button:not([class*="dh-"]))[aria-pressed="true"] { background: var(--row-sel); border-color: var(--warn); color: var(--warn); }
:where(button:not([class*="dh-"])):disabled { color: #5a5866; border-color: var(--control-edge); cursor: not-allowed; }
label { display: block; margin: var(--s-6) 0 var(--s-2); color: var(--text-2); font-size: var(--fs-sm); }
input, select, textarea { background: var(--slot); color: var(--text); border: 1px solid var(--slot-edge); border-radius: 0; padding: var(--s-3) var(--s-4); font: inherit; }
input { width: 100%; } select { max-width: 100%; }
input[type=checkbox], input[type=radio] { width: auto; accent-color: var(--gold-fill); }
::placeholder { color: var(--text-3); }
form button { margin-top: var(--s-7); width: 100%; min-height: 30px; }
.notice { padding: var(--s-3) var(--s-5); color: var(--warn); font-size: var(--fs-sm); }
.notice.error { color: var(--bad); }

/* ---- sign in and hold list ---- */
.login-card { width: min(450px, 100%); margin: var(--s-8) auto; padding: var(--s-8); }
.page-head { margin-bottom: var(--s-8); padding: var(--s-6) var(--s-7); }
.page-head p:last-child { margin-bottom: 0; }
.hold-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(270px, 360px)); gap: var(--s-7); }
.hold-card { display: block; padding: var(--s-7); color: var(--text); }
.hold-card:hover { border-color: var(--warn); color: var(--text); }
.hold-emblem { display: block; margin-bottom: var(--s-8); color: var(--gold); font-size: var(--fs-hero); }
.card-link { display: block; margin-top: var(--s-8); color: var(--warn); font-size: var(--fs-sm); }
.back-link { color: var(--text-2); font-size: var(--fs-sm); }
.hold-header { display: flex; justify-content: space-between; align-items: center; padding: var(--s-8) 0 var(--s-6); }
.hold-header h1 { margin-bottom: var(--s-5); }
.hold-header .muted { font-size: var(--fs-xs); }
.access-badge { padding: var(--s-2) var(--s-4); background: var(--ink-0); color: var(--gold); border: 1px solid var(--gold-dark); font-size: var(--fs-xs); }

/* ---- terrain map base (workspace.css positions it) ---- */
.map-shell { overflow: hidden; background: var(--ink-1); border: 1px solid var(--gold-dark); }
.map-toolbar, .map-footer { display: flex; justify-content: space-between; align-items: center; gap: var(--s-6); padding: var(--s-4) var(--s-6); font-size: var(--fs-sm); }
.map-toolbar { border-bottom: 1px solid var(--gold-dark); }
.map-toolbar button { margin-left: var(--s-3); }
.map-host { position: relative; height: clamp(360px, 58vh, 620px); overflow: hidden; background: var(--ink-1); }
.map-host canvas { display: block; touch-action: none; cursor: grab; } .map-host canvas:active { cursor: grabbing; }
.map-footer { flex-wrap: wrap; color: var(--text-2); border-top: 1px solid var(--gold-dark); }
.selection-info { color: var(--warn); }
.map-diagnostic { position: absolute; top: var(--s-5); left: var(--s-5); padding: var(--s-3) var(--s-4); pointer-events: none;
  background: var(--onmap-bg); color: #f4f0e0; font: var(--fs-xs)/1.45 var(--font-code); text-shadow: none; }
.legend-row { display: flex; align-items: center; gap: var(--s-6); margin: var(--s-7) 0; font-size: var(--fs-sm); }
.swatch { width: 14px; height: 14px; box-shadow: 0 0 0 1px #000; }
.simulation-panel { margin-top: var(--s-8); padding: var(--s-8); background: var(--ink-0); border: 1px solid var(--gold-dark); }
.simulation-panel table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.simulation-panel th, .simulation-panel td { padding: var(--s-4); text-align: left; border-bottom: 1px solid var(--gold-dark); }
.simulation-panel details { margin: var(--s-7) 0; } .simulation-panel label { display: block; margin: var(--s-4) 0; }
.simulation-panel progress { display: block; width: 100%; accent-color: var(--warn); }
.selected-building { border-color: var(--warn); }

/* ---- model preview (/dev/model-preview) ---- */
.preview-workspace { display: grid; grid-template-columns: minmax(360px, .9fr) minmax(440px, 1.1fr); gap: var(--s-8); align-items: start; }
.preview-panel { min-width: 0; padding: var(--s-7); }
.preview-panel h2 { margin: 0 0 var(--s-4); padding: 3px 10px; background: var(--umber); border-top: 1px solid var(--umber-hi); border-bottom: 1px solid var(--umber-lo);
  color: #f4f0e0; text-shadow: 1px 1px 0 #000; font-size: var(--fs-lg); }
.preview-controls { display: flex; gap: var(--s-4); align-items: end; flex-wrap: wrap; margin: var(--s-6) 0; }
.preview-controls input { max-width: 160px; } .preview-controls label { margin: 0; }
.source-editor { width: 100%; height: 420px; padding: var(--s-6); resize: vertical; tab-size: 2; white-space: pre; overflow: auto;
  font: var(--fs-xs)/1.45 var(--font-code); text-shadow: none; }
.preview-panel table { width: 100%; border-collapse: collapse; margin: var(--s-6) 0; font-size: var(--fs-sm); }
.preview-panel th, .preview-panel td { padding: var(--s-2) var(--s-4); text-align: left; border-bottom: 1px solid var(--gold-dark); }
.preview-panel th { color: var(--text-2); }
.preview-panel td input { min-width: 50px; width: 100%; padding: var(--s-2) var(--s-3); }
.preview-panel details { margin: var(--s-7) 0; }
.preview-panel summary { cursor: pointer; color: var(--gold); }
.instance-setup { padding: var(--s-6) 0; border-bottom: 1px solid var(--gold-dark); }
.instance-setup label { display: block; margin: var(--s-4) 0; }
.text-button { min-height: 0; padding: var(--s-1); background: transparent; border: 0; box-shadow: none; color: inherit; font-size: inherit; text-align: left; cursor: pointer; }
.text-button:hover { color: var(--warn); }
.diagnostics { padding-left: var(--s-8); }
.diagnostics .error { color: var(--bad); }
.trace-list { max-height: 280px; overflow: auto; }
.trace-row { display: block; width: 100%; font: var(--fs-xs)/1.6 var(--font-code); text-shadow: none; }
@media (max-width: 1050px) { .preview-workspace { grid-template-columns: 1fr; } }

/* ---- world model (/worlds/{id}/model) ---- */
.model-workspace { display: grid; grid-template-columns: minmax(240px, 320px) minmax(0, 1fr); gap: var(--s-7); align-items: start; margin-top: var(--s-7); }
.model-files, .model-editor, .model-pending { min-width: 0; }
.model-files { max-height: calc(100vh - 220px); overflow-y: auto; }
.model-files .dh-row, .model-dialog .dh-row { width: 100%; text-align: left; }
.model-files .dh-head { margin-top: var(--s-4); } .model-files .dh-head:first-child { margin-top: 0; }
.model-changed { color: var(--warn); } .model-bad { color: var(--bad); }
.model-use { font-family: var(--font-code); font-size: var(--fs-xs); text-shadow: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.model-removed { margin: var(--s-2) var(--s-4); }
.model-definition { display: flex; gap: var(--s-1); align-items: stretch; } .model-definition .dh-row { flex: 1; min-width: 0; } .model-definition .dh-btn { margin-top: var(--gap); white-space: nowrap; }
.model-new { display: flex; gap: var(--s-2); margin: var(--s-3) 0; } .model-new input { min-width: 0; flex: 1; }
.model-actions { display: flex; gap: var(--s-4); align-items: center; flex-wrap: wrap; margin: var(--s-3) 0; }
.model-editor__host { height: calc(100vh - 360px); min-height: 320px; border: 1px solid var(--gold-dark); text-shadow: none; }
.model-editor__host .cm-editor { height: 100%; }
.model-field { height: auto; cursor: default; } .model-field .dh-row__sub { white-space: normal; }
.model-field .dh-row__meta { display: flex; align-items: center; gap: var(--s-2); } .model-field input { width: 120px; } .model-field .model-wide { width: 240px; }
.model-editor .graph-shell { margin-top: var(--s-3); }
.model-diff { margin: var(--s-2) 0; padding: var(--s-3); background: var(--slot); color: var(--text-2); overflow-x: auto; white-space: pre; }
.model-diff span { display: block; } .model-diff__added { color: var(--text); background: var(--row); } .model-diff__removed { color: var(--text-3); text-decoration: line-through; }
.model-preview { max-height: 320px; overflow: auto; margin: 0; padding: var(--s-3); background: var(--slot); color: var(--text); } .model-field input:disabled, .model-field select:disabled { color: var(--text-3); }
.model-editor [role="tabpanel"] .dh-head { margin-top: var(--s-4); }
.commodity-picker { display: inline-flex; align-items: center; gap: var(--s-2); flex: 0 0 auto; } .commodity-picker input { width: 240px; }
.model-actions > input { flex: 0 1 200px; }
.model-terrain-pictures { display: grid; grid-template-columns: repeat(auto-fill, minmax(256px, 1fr)); gap: var(--s-4); margin: var(--s-4) 0; }
.model-terrain-pictures figure { margin: 0; } .model-terrain-pictures img { display: block; width: 100%; image-rendering: pixelated; background: var(--slot); }
.model-field[data-bad="true"] { outline: 1px solid var(--bad); outline-offset: -1px; }
.model-pending { margin-top: var(--s-7); } .model-pending p { margin: var(--s-3) var(--s-4); } .model-pending__name { color: var(--warn); }
.model-pending .dh-code { margin: 0 var(--s-4); padding: var(--s-3); background: var(--slot); color: var(--text); max-height: 200px; overflow: auto; }
.model-dialog { position: fixed; inset: 0; z-index: 20; display: grid; place-items: center; }
.model-dialog .dh-window { width: min(760px, 100vw - 40px); max-height: calc(100vh - 80px); overflow-y: auto; }
.model-dialog .dh-head { margin-top: var(--s-6); } .model-dialog h2 { margin-top: 0; }
.model-dialog .dh-row { height: auto; cursor: default; } .model-finding .dh-row__sub { white-space: normal; }
.model-knot--left { left: -9px; } .model-knot--right { right: -9px; }
@media (max-width: 900px) { .model-workspace { grid-template-columns: 1fr; } .model-files { max-height: 240px; } }


/* ---- behaviour graph (SVG from Graph/graph.ts) ---- */
.graph-shell { margin-top: var(--s-6); overflow: hidden; border: 1px solid var(--gold-dark); }
.graph-host { width: 100%; height: 400px; overflow: hidden; background: var(--ink-1); }
.graph-host svg { width: 100%; height: 100%; touch-action: none; user-select: none; }
.graph-shell > p, .graph-shell > details { margin: var(--s-5) var(--s-6); }
.graph-node { cursor: pointer; }
/* Square everything (DESIGN: radius 0): graph.ts sets rx on states, actions and the state-timing bars; CSS geometry wins. */
.graph-node rect { fill: var(--row); stroke: var(--row-hi); stroke-width: 2; rx: 0; ry: 0; }
.graph-node text { fill: var(--text); font: var(--fs-xs) var(--font-code); pointer-events: none; }
.graph-node.decision rect { fill: var(--umber); stroke: var(--umber-hi); }
.graph-node.wait rect { fill: var(--slot); stroke: var(--slot-ring); }
.graph-node.recent rect { stroke-width: 3; }
.graph-node.active rect { stroke: var(--warn); stroke-width: 3; fill: var(--row-sel); }
.graph-node.waiting rect { stroke: var(--warn); }
.graph-node.fault rect { stroke: var(--bad); fill: var(--stop); }
.graph-edge { cursor: pointer; }
.graph-edge path { fill: none; stroke: var(--gold-dark); stroke-width: 2; }
#graph-arrow path { fill: var(--gold-dark); }
.graph-edge text { fill: var(--info); font: var(--fs-xs) var(--font-code); paint-order: stroke; stroke: var(--ink-1); stroke-width: 4px; }
[data-theme="light"] .graph-host { background: var(--ink-0); }
[data-theme="light"] .graph-edge text { stroke: var(--ink-0); }
.graph-edge.recent path { stroke: var(--warn); stroke-width: 3; }
.graph-edge:focus path { stroke: var(--warn); }
.graph-node .state-timing { pointer-events: none; }
.graph-node .state-timing .state-remaining { fill: var(--text); font: var(--fs-xs) var(--font-code); }
.graph-node .state-timing .state-progress-track { fill: var(--slot); stroke: none; }
.graph-node .state-timing .state-progress-fill { fill: var(--warn); stroke: none; }
/* Umber and stop fills stay dark in parchment, so their labels keep light text (as the design does for .dh-head). */
[data-theme="light"] .graph-node.decision text, [data-theme="light"] .graph-node.fault text { fill: #f4f0e0; text-shadow: 1px 1px 0 #000; }

/* ---- Blazor error bar ---- */
#blazor-error-ui { display: none; position: fixed; left: 0; right: 0; bottom: 0; z-index: 100; padding: var(--s-4) var(--s-8) var(--s-4) var(--s-7); color: var(--bad); }
#blazor-error-ui .reload { margin-left: var(--s-4); color: var(--warn); }
#blazor-error-ui .download { margin-left: var(--s-4); padding: 0; background: none; border: 0; box-shadow: none; color: var(--warn); font: inherit; cursor: pointer; }
#blazor-error-ui .dismiss { position: absolute; top: var(--s-4); right: var(--s-6); padding: 0; background: none; border: 0; box-shadow: none; color: var(--text); font: inherit; cursor: pointer; }

/* ---- roles page: one row per player, a drawn .dh-check per role (the native input lies transparent on top, as on the policies tab) ---- */
.admin-roles { overflow-x: auto; }
.admin-roles table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.admin-roles th, .admin-roles td { padding: var(--s-3) var(--s-4); text-align: left; vertical-align: middle; border-bottom: 1px solid var(--gold-dark); }
.admin-roles thead th { color: var(--text-2); }
.admin-roles tbody th { color: var(--text); font-weight: inherit; }
.admin-roles__sub, .admin-roles__login { display: block; color: var(--text-2); font-size: var(--fs-xs); }
.admin-roles .dh-checkbox > input[type=checkbox] { position: absolute; inset: 0; width: 100%; height: 100%; min-height: 0; margin: 0; padding: 0; opacity: 0; cursor: pointer; }
.admin-roles .dh-checkbox > input[type=checkbox]:disabled { cursor: not-allowed; }
@media (pointer: coarse) { .admin-roles .dh-checkbox, .admin-roles .dh-checkbox > .dh-check { width: var(--hit); height: var(--hit); } }

@media (max-width: 900px) {
  .brand-subtitle { display: none; }
  .app-header { justify-content: space-between; padding: var(--s-3) var(--s-6); }
  .app-main { padding: var(--s-8) var(--s-6); }
  .app-footer span { display: none; }
}

/* Coarse pointers (README §8): 44px targets and 16px inputs for the app's own controls; hold-theme.css covers the .dh-* ones.
   Last in the file so it beats the base input font shorthand, .source-editor and form button above. */
@media (pointer: coarse) {
  input, select, textarea, .source-editor { font-size: 16px; }
  :where(button:not([class*="dh-"])), .button, form button { min-height: 44px; }
}
.equipment-wait { color: var(--warn); }
