/* App-specific layout, built on top of ds.css tokens/components. */
html, body { height: 100%; }
body { overflow: hidden; }
/* Height, on a phone, is not 100vh.
   iOS Safari and Android Chrome define `vh` against the viewport with the
   browser toolbars HIDDEN, so 100vh is taller than what you can actually see
   and the bottom of the app sits behind the URL bar. That is invisible on a
   desktop and invisible under device emulation (no dynamic browser chrome),
   but on a real handset it swallowed the entire build action bar.
   `dvh` is the dynamic viewport unit that tracks the visible area; --app-h is
   set from visualViewport in app.js for browsers older than that. */
#app { height: 100vh; height: 100dvh; height: var(--app-h, 100dvh); display: flex; flex-direction: column; }
.hidden { display: none !important; }

/* ---------- entry screen ---------- */
#entry-screen { height: 100%; display: grid; place-items: center; background: var(--color-bg); }
.entry-card { width: min(560px, 92vw); max-height: 92vh; border-radius: calc(var(--radius-lg) * 1.15); overflow: hidden; box-shadow: var(--shadow-lg); background: var(--color-surface); display: flex; flex-direction: column; }
.entry-hero { height: 140px; flex: none; background: var(--color-accent-2-200); position: relative; overflow: hidden; }
.entry-hero::before { content: ''; position: absolute; inset: 0; background:
  repeating-linear-gradient(0deg, color-mix(in srgb, #201e1d 6%, transparent) 0 1px, transparent 1px 14px),
  repeating-linear-gradient(90deg, color-mix(in srgb, #201e1d 6%, transparent) 0 1px, transparent 1px 14px); }
.entry-hero .c1 { position: absolute; left: 40px; top: 28px; width: 84px; height: 84px; border-radius: 999px; background: var(--color-accent-300); }
.entry-hero .c2 { position: absolute; left: 112px; top: 60px; width: 54px; height: 54px; border-radius: 999px; background: var(--color-accent); }
.entry-hero .stat { position: absolute; right: 20px; bottom: 14px; font-family: var(--font-heading); font-size: 14px; color: var(--color-accent-900); }
.entry-body { padding: 20px 24px 24px; display: flex; flex-direction: column; gap: 14px; overflow: auto; min-height: 0; }
.rules { display: flex; flex-direction: column; gap: 10px; max-height: 260px; overflow: auto; padding-right: 4px; font-size: 13px; line-height: 1.55; color: color-mix(in srgb, var(--color-text) 85%, transparent); }
.rules p { margin: 0; }
.terrain-field { font-size: 13px; display: flex; flex-direction: column; gap: 8px; }
.terrain-field summary { cursor: pointer; font-weight: 600; }
.terrain-field p { margin: 6px 0; font-size: 12px; line-height: 1.5; color: color-mix(in srgb, var(--color-text) 75%, transparent); }
.terrain-field[open] { padding-bottom: 4px; }
.terrain-row { display: flex; flex-wrap: wrap; gap: 6px 14px; margin-top: 6px; }
.terrain-row label { display: flex; align-items: center; gap: 6px; font-size: 12px; }
.terrain-row .small-input { width: 90px; }
.entry-error { font-size: 12px; color: #a02c22; min-height: 0; }
.entry-error:empty { display: none; }
/* The server's sign-in panel (js/net/account.js); never drawn single-player. */
.account-panel, .account-form { display: flex; flex-direction: column; gap: 10px; }
.account-mode { align-self: flex-start; }
.account-hint { margin: 0; font-size: 12px; line-height: 1.5; color: color-mix(in srgb, var(--color-text) 70%, transparent); }
.account-change summary { cursor: pointer; font-size: 13px; font-weight: 600; }
.account-change[open] summary { margin-bottom: 8px; }

/* ---------- top bar ----------
   One row, about 44px: the city, three headline figures (the rest behind
   "⋯"), the tabs, and the clock. It used to be two bars, 97px at 1920 wide
   and 115px at 1366, where seven stat tags wrapped onto a second line. */
.topbar { display: flex; align-items: center; gap: 12px; padding: 6px 14px; min-height: 44px; border-bottom: 1px solid var(--color-divider); background: var(--color-surface); flex: none; }
.topbar .brand { font-family: var(--font-heading); font-size: 18px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 200px; flex: 0 1 auto; min-width: 0; }
.topbar .stats { display: flex; gap: 6px; flex: none; align-items: center; }
.topbar .stat { border: 0; font: inherit; font-size: 12px; cursor: pointer; white-space: nowrap; }
.topbar .stat:hover { box-shadow: 0 0 0 1px var(--color-divider); }
.stats-more { position: relative; display: inline-flex; }
.stats-more-btn { min-width: 30px; justify-content: center; }
.stats-pop { display: none; position: absolute; top: calc(100% + 6px); left: 0; z-index: 60; flex-direction: column; align-items: flex-start; gap: 6px; padding: 8px; background: var(--color-surface); border: 1px solid var(--color-divider); border-radius: 12px; box-shadow: var(--shadow-md); }
/* Bridges the gap so the pointer can travel from the button to the list. */
.stats-pop::before { content: ''; position: absolute; left: 0; right: 0; top: -8px; height: 8px; }
.stats-more:hover .stats-pop, .stats-more:focus-within .stats-pop, .stats-more.open .stats-pop { display: flex; }
.topbar .right { margin-left: auto; display: flex; align-items: center; gap: 10px; font-size: 13px; flex: 0 1 auto; min-width: 0; }
.topbar .right #dayLabel { white-space: nowrap; }
/* The clock and the speed control never give way; on a server the event
   ticker does, down to nothing (the journal lists every event), unless it is
   saying the connection is gone. */
.topbar .right > .seg, .topbar .right > #dayLabel { flex: none; }
#netFeed { flex: 0 1 auto; min-width: 0; max-width: 300px; }
#netFeed.tag-accent { flex: none; max-width: 360px; }
@media (max-width: 1600px) {
  .topbar { gap: 10px; }
  .topbar .tabbtn { padding: 5px 8px; font-size: 12.5px; }
}
/* A server's top bar carries gold and a Trade tab too. Below 1440px the
   ticker goes (the journal's city view lists every event). */
@media (max-width: 1440px) {
  #netFeed:not(.tag-accent) { display: none; }
}
/* When even that won't fit one row (a narrow window, a long city name), the
   tabs take a row of their own rather than scrolling out of sight or pushing
   the clock off the edge. app.js (fitTopbar) measures and sets the class. */
.topbar.stacked { flex-wrap: wrap; row-gap: 4px; }
.topbar.stacked .tabbar { order: 4; flex: 1 0 100%; }

/* ---------- tabs ---------- */
.tabbar { display: flex; gap: 6px; padding: 8px 20px 0; background: var(--color-bg); flex: none; }
.tabbtn { border: 1px solid var(--color-divider); border-bottom: none; border-radius: 10px 10px 0 0; padding: 7px 14px; font: 600 13px var(--font-body); background: var(--color-surface); cursor: pointer; color: var(--color-text); }
.tabbtn.on { background: var(--color-accent); color: var(--color-bg); border-color: var(--color-accent); }
/* The main tabs live in the top bar as pills. Too narrow for all of them and
   the row scrolls sideways rather than wrapping. */
.topbar .tabbar { flex: 1 1 auto; min-width: 0; gap: 2px; padding: 0; background: transparent; overflow-x: auto; scrollbar-width: none; }
.topbar .tabbar::-webkit-scrollbar { display: none; }
.topbar .tabbtn { flex: none; border: 0; border-radius: 999px; padding: 5px 11px; background: transparent; white-space: nowrap; }
.topbar .tabbtn:hover { background: color-mix(in srgb, var(--color-accent) 12%, transparent); }
.topbar .tabbtn.on { background: var(--color-accent); color: var(--color-bg); }
.tabpanel { flex: 1; min-height: 0; display: none; }
.tabpanel.on { display: flex; flex-direction: column; }

/* ---------- build tab ----------
   Desktop: the build rail on the left, the map in the middle with the
   inspector drawer under it, the journal on the right. The phone keeps its
   own layout (css/mobile.css): the dock and the asset rail as bottom sheets.
   Measured at 1366x768 before this layout, the map had 22% of the window. */
#tab-build { flex: 1; min-height: 0; }
.build-main { flex: 1; display: flex; min-height: 0; }
.map-stack { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; position: relative; }
.map-col { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 8px; padding: 8px 10px; min-width: 0; position: relative; }
.map-toolbar { display: flex; align-items: center; gap: 12px; font-size: 12px; }
.map-toolbar .spacer { margin-left: auto; display: flex; align-items: center; gap: 8px; }
.ground-label { color: color-mix(in srgb, var(--color-text) 70%, transparent); white-space: nowrap; }
.ground-label .steep { color: #a02c22; }
#gridCanvas { border-radius: 12px; border: 1px solid var(--color-divider); background: #efe6d3; cursor: crosshair; touch-action: none; display: block; align-self: flex-start; }
/* The map's readouts float over its corners instead of taking two rows.
   grid.js leaves absolutely positioned children out when it sizes the map. */
.map-hud-top, .map-hud-bottom { position: absolute; left: 18px; right: 18px; z-index: 5; pointer-events: none; align-items: flex-start; gap: 8px; }
.map-hud-top { top: 16px; }
.map-hud-bottom { bottom: 16px; align-items: flex-end; }
.map-hud-top > *, .map-hud-bottom > * { pointer-events: auto; }
.hud-pill, #mapStatus, .hud-draft, .map-legend { background: color-mix(in srgb, var(--color-surface) 90%, transparent); border: 1px solid var(--color-divider); border-radius: 999px; padding: 3px 10px; box-shadow: var(--shadow-sm); }
.hud-where { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
#mapStatus { max-width: 60%; }
#mapStatus:empty { display: none; }
/* The draft controls show only while a tool can draw one. */
.hud-draft.idle { display: none; }
.hud-draft .btn { min-height: 24px; padding-block: 2px; }
.hud-tool { font-weight: 600; }
.hud-tool:empty { display: none; }
.map-legend { display: flex; align-items: center; gap: 4px; font-size: 12px; padding: 2px 4px; position: relative; }
.map-legend .btn-icon { width: 24px; height: 24px; min-height: 0; font-size: 11px; }
.map-legend .sw { width: 11px; height: 11px; border-radius: 3px; display: inline-block; margin-right: 5px; vertical-align: -1px; }
.legend-pop:not([hidden]) { position: absolute; right: 0; bottom: calc(100% + 8px); display: flex; flex-direction: column; gap: 5px; padding: 10px 12px; background: var(--color-surface); border: 1px solid var(--color-divider); border-radius: 12px; box-shadow: var(--shadow-md); white-space: nowrap; color: var(--color-text); }
.legend-help { max-width: 230px; white-space: normal; font-size: 11px; color: color-mix(in srgb, var(--color-text) 70%, transparent); border-top: 1px solid var(--color-divider); padding-top: 6px; }

/* ---- the build rail: one button per category, a flyout of buildings ---- */
.build-rail { width: 60px; flex: none; display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 8px 0; border-right: 1px solid var(--color-divider); background: var(--color-surface); overflow-y: auto; scrollbar-width: none; }
.rail-btn { width: 50px; display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 6px 0 5px; border: 0; border-radius: 10px; background: transparent; color: var(--color-text); font: inherit; cursor: pointer; position: relative; }
.rail-btn svg { width: 22px; height: 22px; display: block; }
.rail-btn span { font-size: 9.5px; line-height: 1.1; }
.rail-btn:hover { background: color-mix(in srgb, var(--color-accent) 12%, transparent); }
.rail-btn.open { background: var(--color-accent-100); box-shadow: inset 0 0 0 1px var(--color-accent-300); }
.rail-btn.on { background: var(--color-accent); color: var(--color-bg); }
.rail-sep { width: 32px; height: 1px; background: var(--color-divider); margin: 4px 0; flex: none; }
.build-flyout { position: absolute; left: 8px; top: 8px; z-index: 20; width: 304px; max-height: calc(100% - 16px); overflow-y: auto; background: var(--color-surface); border: 1px solid var(--color-divider); border-radius: 14px; box-shadow: var(--shadow-lg); padding: 10px; display: flex; flex-direction: column; gap: 8px; }
.fly-head { display: flex; align-items: center; gap: 8px; }
.fly-head h6 { margin: 0; }
.fly-head .btn { margin-left: auto; font-size: 11px; min-height: 24px; padding: 2px 8px; }
.fly-head .btn + .btn { margin-left: 0; }
.fly-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.fly-item { display: flex; flex-direction: column; align-items: center; gap: 3px; padding: 8px 4px 6px; border: 1px solid var(--color-divider); border-radius: 10px; background: var(--color-bg); cursor: pointer; font: inherit; color: var(--color-text); text-align: center; min-width: 0; }
.fly-item:hover, .fly-item:focus-visible { border-color: var(--color-accent-400); outline: none; }
.fly-item.active { border-color: var(--color-accent); background: var(--color-accent-100); box-shadow: 0 0 0 1px var(--color-accent); }
.fly-item .sw { width: 30px; height: 30px; border-radius: 7px; display: grid; place-items: center; font-size: 15px; }
.fly-item .lbl { font-size: 11px; font-weight: 600; line-height: 1.15; }
.fly-item .cost { font-size: 10.5px; font-family: var(--font-heading); }
.fly-opts { display: flex; flex-direction: column; gap: 4px; border-top: 1px solid var(--color-divider); padding-top: 8px; }
.build-card { position: absolute; z-index: 21; width: 310px; background: var(--color-surface); border: 1px solid var(--color-divider); border-radius: 14px; box-shadow: var(--shadow-lg); padding: 12px; display: flex; flex-direction: column; gap: 8px; font-size: 12px; pointer-events: none; }
.build-card h6 { margin: 0; }
.bc-head { display: flex; align-items: center; gap: 8px; }
.bc-head .sw { width: 28px; height: 28px; border-radius: 7px; display: grid; place-items: center; font-size: 14px; flex: none; }
.bc-head .ttl { font-family: var(--font-heading); font-size: 15px; line-height: 1.1; }
.bc-facts { display: flex; flex-wrap: wrap; gap: 5px; }
.bc-note { display: -webkit-box; -webkit-line-clamp: 5; -webkit-box-orient: vertical; overflow: hidden; }
.foot-glyph { display: inline-grid; gap: 1px; vertical-align: middle; margin-right: 4px; }
.foot-glyph i { width: 6px; height: 6px; border-radius: 1px; display: block; }

/* ---- the inspector drawer under the map ----
   Its height is a share of the room (28% unless dragged), so it is the same
   proportion of a 1080p window as of a 4K one. Its cards fill it: panels.js
   (inspectorLayout) picks the rows and columns that make them biggest and a
   type scale --k (12px at 1), and sets --ic/--ir; every size inside a card
   is in em, so the whole card scales with --k. */
.inspector { flex: none; height: calc(var(--insp-frac, 0.28) * 100%); min-height: 210px; max-height: calc(100% - 160px); display: flex; flex-direction: column; border-top: 1px solid var(--color-divider); background: var(--color-surface); position: relative; }
.inspector.min { height: auto; min-height: 0; }
.inspector.min .insp-body { display: none; }
.insp-grip { position: absolute; top: -5px; left: 0; right: 0; height: 9px; cursor: ns-resize; z-index: 2; }
.inspector.min .insp-grip { display: none; }
.insp-head { display: flex; align-items: center; gap: .65em; padding: .5em 1em; border-bottom: 1px solid var(--color-divider); flex: none; min-width: 0; font-size: calc(12px * var(--k, 1)); }
.insp-head .ttl { font-family: var(--font-heading); font-size: 1.25em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.insp-head .ttl .nm { font-size: 1em !important; }
.insp-head .subtle { font-size: .92em; }
.insp-head .btn { font-size: .92em; min-height: 2em; padding: .15em .65em; }
.insp-head .btn svg { width: 1.2em; height: 1.2em; }
.insp-body { flex: 1; min-height: 0; overflow: hidden; padding: 8px 12px 10px; display: flex; flex-direction: column; gap: 6px; font-size: calc(12px * var(--k, 1)); line-height: 1.3; }
.insp-body.cramped { overflow: auto; }
.insp-strip { flex: none; display: flex; flex-wrap: wrap; align-items: center; gap: .25em 1.2em; }
.insp-bar { display: inline-block; width: 8em; height: .6em; }
.insp-cols { flex: 1; min-height: 0; display: grid; gap: 10px; grid-template-columns: repeat(var(--ic, 6), minmax(0, 1fr)); grid-template-rows: repeat(var(--ir, 1), minmax(0, 1fr)); }
.insp-body.cramped .insp-cols { flex: none; grid-template-columns: repeat(var(--ic), var(--cw)); grid-template-rows: repeat(var(--ir), var(--ch)); }
.icard { min-width: 0; min-height: 0; overflow: hidden; display: flex; flex-direction: column; gap: .3em; padding: .55em .75em; border-radius: var(--radius-md); background: color-mix(in srgb, var(--color-bg) 55%, var(--color-surface)); }
.icard.scroll { overflow-y: auto; }
.icard h6 { margin: .2em 0 0; font-size: .8em; }
.icard h6:first-child { margin-top: 0; }
.insp-body .kv { font-size: 1em; gap: .6em; }
.insp-body .kv > :first-child { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.insp-body .kv > :last-child { text-align: right; white-space: nowrap; }
.icard .table { font-size: .95em !important; width: 100%; }
.icard .table th, .icard .table td { padding: .12em .35em; line-height: 1.3; }
/* ds.css fixes table headings at 11px; here they scale with the card. */
.icard .table th { font-size: .78em; }
.icard .card { font-size: 1em !important; padding: 0 !important; background: none !important; gap: .3em !important; }
.u-card .kv:first-child strong { font-size: 1.05em; }
.u-chart { flex: 1 1 0; min-height: 0; width: 100%; display: block; overflow: visible; }
.eff-curve { flex: 1 1 3em; min-height: 1.6em; width: 100%; display: block; }
.icard .spark { flex: 1 1 3em; min-height: 1.6em; width: 100%; display: block; }

/* ---- the journal on the right ---- */
.rail-col { width: 340px; flex: none; border-left: 1px solid var(--color-divider); padding: 12px; display: flex; flex-direction: column; gap: 10px; overflow: hidden; background: var(--color-surface); }
.rail-col .card { box-shadow: none; background: color-mix(in srgb, var(--color-bg) 55%, var(--color-surface)); }
.asset-sheet { display: none; }
.journal-side { display: flex; flex-direction: column; gap: 8px; min-height: 0; flex: 1; }
.js-head { display: flex; flex-direction: column; gap: 6px; flex: none; }
.js-head .row { display: flex; align-items: center; gap: 6px; min-width: 0; }
.js-head .row .btn { font-size: 11px; min-height: 24px; padding: 2px 8px; }
.js-collapse { margin-left: auto; }
.js-filters { display: flex; gap: 4px; flex: none; align-items: center; }
.js-filters .tag { border: 0; font: inherit; font-size: 11px; cursor: pointer; }
.js-list { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; }
.jr { display: grid; grid-template-columns: 46px minmax(0, 1fr) auto; gap: 1px 8px; padding: 5px 2px; border-bottom: 1px solid color-mix(in srgb, var(--color-text) 7%, transparent); font-size: 11.5px; align-items: baseline; }
.jr-time { font-size: 10px; color: color-mix(in srgb, var(--color-text) 55%, transparent); white-space: nowrap; }
.jr-what { min-width: 0; overflow-wrap: anywhere; }
.jr-amt { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.jr-amt.in { color: var(--color-accent-2-700); }
.jr-amt.out { color: var(--color-accent-700); }
.jr-sub { grid-column: 2 / 4; font-size: 10px; color: color-mix(in srgb, var(--color-text) 60%, transparent); overflow-wrap: anywhere; }
.jr-kind { font-size: 8.5px; letter-spacing: .06em; text-transform: uppercase; color: color-mix(in srgb, var(--color-text) 50%, transparent); margin-right: 4px; }
.jr-day { font-size: 10px; letter-spacing: .06em; text-transform: uppercase; color: var(--color-accent-700); padding: 8px 2px 2px; }
/* Collapsed, the journal is a strip with one button to bring it back. */
.rail-col.collapsed { width: 40px; padding: 10px 4px; align-items: center; }
.rail-col.collapsed .js-filters, .rail-col.collapsed .js-list, .rail-col.collapsed .js-head > :not(.row), .rail-col.collapsed .js-head .row > :not(.js-collapse) { display: none; }
.rail-col.collapsed .js-collapse { margin: 0; }

/* The phone's Build sheet; a desktop builds from the rail. */
.dock-row { display: none; height: 300px; flex: none; border-top: 1px solid var(--color-divider); background: var(--color-surface); gap: 14px; padding: 12px 16px; }
.dock-pal { width: 630px; flex: none; display: flex; flex-direction: column; gap: 8px; min-height: 0; }
.dock-pal .items { display: flex; flex-wrap: wrap; gap: 7px; overflow: auto; }
.pal-item { width: 132px; border: 1px solid var(--color-divider); border-radius: 10px; padding: 7px 8px; display: flex; flex-direction: column; gap: 3px; background: var(--color-bg); cursor: pointer; text-align: left; font: inherit; }
.pal-item.active { border-color: var(--color-accent); background: var(--color-accent-100); box-shadow: 0 0 0 1px var(--color-accent); }
.pal-item .row { display: flex; align-items: center; gap: 6px; }
.pal-item .sw { width: 20px; height: 20px; border-radius: 5px; display: grid; place-items: center; font-size: 11px; flex: none; }
.pal-item .lbl { font-size: 12px; font-weight: 600; line-height: 1.1; }
.pal-item .cost { font-family: var(--font-heading); font-size: 12px; }
.pal-item .foot { font-size: 9px; letter-spacing: .04em; text-transform: uppercase; color: color-mix(in srgb, var(--color-text) 55%, transparent); }
.road-levels:not(.hidden) { display: flex; flex-direction: column; gap: 4px; margin-top: 2px; flex: none; }
.road-opt-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }

.dock-info { width: 290px; flex: none; display: flex; flex-direction: column; gap: 8px; min-height: 0; }
.io-cols { display: flex; gap: 14px; overflow: auto; font-size: 12px; }
.io-col { flex: 1; }
.io-col h6 { margin: 0 0 4px; }
.io-line { display: flex; justify-content: space-between; gap: 8px; padding: 2px 0; border-bottom: 1px solid color-mix(in srgb, var(--color-text) 7%, transparent); }

.dock-fn { flex: 1; display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.fn-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 7px; overflow: auto; }
.fn-card { background: var(--color-neutral-100); border-radius: var(--radius-md); padding: 6px 8px; display: flex; flex-direction: column; gap: 3px; }
.fn-bar { height: 5px; border-radius: 999px; background: var(--color-neutral-300); overflow: hidden; }
.fn-bar i { display: block; height: 100%; background: var(--color-accent); }

/* ---------- generic reusable bits ---------- */
.meter-track { height: 8px; border-radius: 999px; background: var(--color-neutral-300); overflow: hidden; }
.meter-track i { display: block; height: 100%; border-radius: 999px; background: var(--color-accent-2-500); }
.kv { display: flex; justify-content: space-between; font-size: 13px; }
.subtle { font-size: 11px; }
.section-title { margin: 8px 0 6px; }
.pencil-btn { border: none; background: transparent; cursor: pointer; color: var(--color-accent); display: inline-flex; padding: 2px; }
.pencil-btn svg { display: block; }
.editrow { display: inline-flex; align-items: center; gap: 4px; }
.small-input { font-size: 12px; min-height: 26px; width: 170px; }

/* ---------- books tab ---------- */
#tab-books .books-stack { flex: 1; overflow: auto; padding: 4px 20px 24px; display: flex; flex-direction: column; gap: 18px; max-width: 900px; }
.books-section { padding: 14px 18px; border: 1px solid var(--color-divider); border-radius: var(--radius-md); background: var(--color-surface); }
.books-section .table { width: 100%; }
.grouphead { cursor: pointer; user-select: none; }
.sec-label { font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--color-accent); padding: 8px 4px 4px; }

/* ---------- tax tab ---------- */
#tab-tax { padding: 16px 20px; overflow: auto; gap: 14px; max-width: 640px; }
#tab-tax input[type=range] { width: 100%; accent-color: var(--color-accent); }

/* ---------- market tab ---------- */
#tab-market { padding: 16px 20px; overflow: auto; gap: 14px; }
.res-picker { display: flex; flex-wrap: wrap; gap: 6px; }
.res-chip { border: 1px solid var(--color-divider); border-radius: 999px; padding: 4px 12px; font-size: 12px; cursor: pointer; background: var(--color-surface); }
.res-chip.on { background: var(--color-accent); color: var(--color-bg); border-color: var(--color-accent); }

/* No inner max-height/overflow here on purpose: a flex item with
   non-visible overflow gets an automatic min-height of 0 per the flexbox
   spec, so it was collapsing to a 0px scrollbox instead of ever showing —
   the transaction history is meant to make the *page* taller and scroll
   with #tab-market's own overflow:auto, not scroll in a tiny box of its own. */
.mkt-txlog table { width: 100%; }
.mkt-txlog tbody tr:hover { background: var(--color-accent-100); }

/* ---------- roads tab ---------- */
#tab-roads.on { display: grid; padding: 16px 20px; overflow: auto; grid-template-columns: 1fr 1fr; gap: 16px; align-content: start; }
.dist-matrix { border-collapse: collapse; }
.dist-matrix th, .dist-matrix td { border: 1px solid #000; padding: 3px 6px; }
.dist-matrix tbody tr:nth-child(even) { background: color-mix(in srgb, var(--color-text) 6%, transparent); }

/* ---------- companies tab ---------- */
#tab-companies.on { display: flex; flex-direction: column; min-height: 0; }
.companies-list, .company-detail { flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: auto; }
.companies-table { cursor: default; }
.companies-table tbody tr { cursor: pointer; }
.companies-table tbody tr:hover { background: var(--color-accent-100); }
.cd-content table { width: 100%; }
.cd-content .books-section { max-width: 760px; }

#tab-analytics { padding: 16px 20px; overflow: auto; }

/* ---------- trade tab (the server's, OWNERSHIP Phase 6b) ---------- */
#tab-trade { padding: 16px 20px; overflow: auto; gap: 12px; max-width: 900px; }
.trade-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.trade-col { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.trade-item { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: 13px; }
.trade-x { padding: 0 6px; font-size: 12px; }
.trade-history td { vertical-align: top; }
@media (max-width: 820px) { .trade-cols { grid-template-columns: 1fr; } }

/* ---------- analytics small multiples ---------- */
.smgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 12px; }
.smcard { padding: 10px 12px; }
.smcard svg { width: 100%; height: 60px; display: block; }

/* ---------- axis line charts (util.js axisLineChart) ---------- */
.axis-chart { cursor: crosshair; }
.axis-chart-crosshair { position: absolute; top: 8px; bottom: 16px; width: 1px; background: var(--color-text); opacity: .35; display: none; pointer-events: none; }
.axis-chart-tooltip { position: absolute; top: 2px; display: none; pointer-events: none; background: var(--color-surface); border: 1px solid var(--color-divider); border-radius: 6px; padding: 2px 6px; font-size: 10px; font-family: var(--font-body); white-space: nowrap; box-shadow: var(--shadow-sm); z-index: 2; color: var(--color-text); }

::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-thumb { background: var(--color-neutral-400); border-radius: 999px; }

/* The phone's asset sheet (once the desktop's selected-asset rail) carries
   the widest tables in the app (needs fulfilled, and the compact transaction
   ledger). At 308px they forced a horizontal scrollbar. Every table inside is
   pinned to the available width with a fixed layout so a long counterparty
   name wraps instead of pushing the whole row sideways. */
.rail-col table.table { width: 100%; table-layout: fixed; }
.rail-col table.table td, .rail-col table.table th { overflow-wrap: anywhere; }
.rail-col .meter-track { min-width: 46px; }

/* Companies table: compressed to sit comfortably in a square window. */
.companies-table { width: 100%; table-layout: fixed; font-size: 12px; }
.companies-table th, .companies-table td { padding: 5px 6px; overflow-wrap: anywhere; }
.companies-table th.sortable { cursor: pointer; user-select: none; white-space: nowrap; }
.companies-table th.sortable:hover { color: var(--color-accent-700); }
.sort-arrow { display: inline-block; width: 10px; opacity: .35; font-size: 9px; }
.sort-arrow.on { opacity: 1; color: var(--color-accent-700); }

/* Utility Score: total-score bar across the top of the tab. */
.util-total-track { height: 12px; border-radius: 6px; background: var(--color-neutral-200); overflow: hidden; }
.util-total-track > i { display: block; height: 100%; background: var(--color-accent-2-600); border-radius: 6px; }
.ledger-link { color: var(--color-accent-700); cursor: pointer; text-decoration: none; border-bottom: 1px dotted currentColor; }
.ledger-link:hover { color: var(--color-accent-800); }

/* ---------- market order tables ----------
   Geometry is fixed on purpose. The book turns over completely every tick, so
   a table that sizes itself to its contents jitters every column sideways
   several times a second and nothing below it can be read. `table-layout:
   fixed` honours the colgroup ratios instead of the text, the row height is
   pinned, and the render pads the body out to a constant row count — so the
   only thing that ever moves a column is resizing the window. */
.mkt-table { table-layout: fixed; width: 100%; }
.mkt-table .mkt-cell { height: 26px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mkt-table .mkt-cell .editrow { max-width: 100%; overflow: hidden; }
.mkt-table .mkt-cell .nm { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mkt-table tr.mkt-blank td { color: transparent; }
.mkt-table th.mkt-sort { cursor: pointer; }
.mkt-table th.mkt-sort:hover { color: var(--color-accent-700); }
.mkt-table th.mkt-sort.on { color: var(--color-accent-700); }
.mkt-table tr.mkt-ctl td { border-bottom: none; padding-top: 4px; }
.mkt-table .mkt-more { font-size: 11px; padding: 2px 8px; min-height: 22px; }
.mkt-table .mkt-more[disabled] { opacity: .35; cursor: default; }
