A reload icon sits beside the ammo count in the readied-weapon strip and the weapons table, for any weapon with a magazine. It tops the weapon up from its reserve (rules.reloadFor, spot-checked), posts the new count and the weapon's reload time to chat, and warns when the weapon is already full or the reserve is empty. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2025 lines
93 KiB
CSS
2025 lines
93 KiB
CSS
/* ============================================================
|
||
RingBRP — visual system v2
|
||
|
||
Corrected after design critique. The governing principle:
|
||
USE THE COVER FOR IDENTITY, THE INTERIOR AND THE ORIGINAL
|
||
CHARACTER SHEET FOR INFORMATION ARCHITECTURE.
|
||
v1 used the cover for everything, which produced a branding
|
||
exercise rather than a working tool.
|
||
|
||
Sources, sampled not guessed:
|
||
· Cover — ultramarine #18268d, lemon yellow (hue 57°), white.
|
||
· Interior — Swiss grid; heavy rule above a section head and a
|
||
thin rule below; Helvetica body; multi-column category boxes.
|
||
· Explorer sheet — characteristics paired with their derived
|
||
rolls on one line; skills in columnar category boxes; the
|
||
weapons table always visible at the foot, never hidden.
|
||
|
||
Type — four registers, two families, one webfont:
|
||
· Display Michroma, ONLY at the 18px name and 11px section heads.
|
||
· Utility Helvetica Bold 10px caps — every small label.
|
||
· Body Helvetica 13px/1.3.
|
||
· Data Helvetica Bold with tabular figures. Mono is reserved
|
||
for band strings and dice output.
|
||
|
||
Colour roles are separated. YELLOW MEANS ROLLABLE OR ACTIVE.
|
||
Passive numbers are white. That distinction is the whole point,
|
||
and v1 lost it by making every value yellow.
|
||
============================================================ */
|
||
|
||
@font-face {
|
||
font-family: "Michroma";
|
||
src: url("../fonts/Michroma-Regular.woff2") format("woff2");
|
||
font-weight: 400;
|
||
font-display: swap;
|
||
}
|
||
|
||
/* ============================================================
|
||
DESIGN TOKENS — declared once, on :root
|
||
============================================================
|
||
These used to be declared on the component classes themselves
|
||
(.ringbrp-sheet, .ringbrp-chat, .ringbrp-window). That works right up until somebody
|
||
adds a NEW component: journals got their own class, inherited no tokens, and every
|
||
var() in forty rules silently resolved to nothing — which CSS treats as "unset"
|
||
rather than as an error, so the numeric properties applied and every colour did not.
|
||
R-250, and it cost four wrong diagnoses.
|
||
|
||
On :root they are available to anything this system renders, anywhere in the
|
||
document, including UI Foundry mounts outside a sheet: tooltips, context menus,
|
||
notifications, dialogs, and whatever gets added next. Prefixed --rb-, so nothing
|
||
here can collide with Foundry's own custom properties or another module's. */
|
||
|
||
:root {
|
||
/* sampled from the 1984 Explorer Book cover */
|
||
--rb-void: #0c125b;
|
||
--rb-deep: #101a6e;
|
||
--rb-blue: #18268d;
|
||
--rb-panel: #16215f;
|
||
|
||
/* structure — lifted so non-text contrast is actually visible */
|
||
--rb-line: #6674d8; /* 3.1:1 on the page ground */
|
||
--rb-hairline: #4d5ac0; /* 2.2:1 — decorative separators only */
|
||
|
||
--rb-yellow: #f2ea72;
|
||
--rb-yellow-dim: rgba(242, 234, 114, 0.45);
|
||
--rb-white: #ecefee;
|
||
--rb-muted: #a8b2e3; /* 5.96:1 on the lightest ground */
|
||
|
||
--rb-danger: #ff7a5c;
|
||
--rb-good: #86e5b0;
|
||
|
||
--rb-display: "Michroma", "Eurostile", sans-serif;
|
||
--rb-body: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||
--rb-mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
|
||
}
|
||
|
||
/* ============================================================
|
||
Frame — flat spot colour, no gradients
|
||
============================================================ */
|
||
|
||
.ringbrp-sheet {
|
||
background: var(--rb-deep);
|
||
color: var(--rb-white);
|
||
font-family: var(--rb-body);
|
||
font-size: 13px;
|
||
line-height: 1.3;
|
||
height: 100%;
|
||
display: flex;
|
||
flex-direction: column;
|
||
box-shadow: inset 0 0 0 1px var(--rb-yellow-dim);
|
||
}
|
||
|
||
.ringbrp-sheet input,
|
||
.ringbrp-sheet select,
|
||
.ringbrp-sheet textarea {
|
||
background: var(--rb-void);
|
||
border: 1px solid var(--rb-line);
|
||
color: var(--rb-white);
|
||
border-radius: 0;
|
||
padding: 2px 5px;
|
||
font-family: var(--rb-body);
|
||
font-size: 13px;
|
||
}
|
||
.ringbrp-sheet input:focus,
|
||
.ringbrp-sheet select:focus,
|
||
.ringbrp-sheet textarea:focus {
|
||
border-color: var(--rb-yellow);
|
||
box-shadow: none;
|
||
outline: 1px solid var(--rb-yellow);
|
||
}
|
||
.ringbrp-sheet a { color: var(--rb-white); cursor: pointer; text-decoration: none; }
|
||
.ringbrp-sheet a[data-action^='roll'], .ringbrp-sheet .rb-char-x5,
|
||
.ringbrp-sheet .rb-skill-name, .ringbrp-sheet .rb-add { color: var(--rb-yellow); }
|
||
.ringbrp-sheet a:hover { color: #fff; text-shadow: none; }
|
||
.ringbrp-sheet ::-webkit-scrollbar { width: 10px; }
|
||
.ringbrp-sheet ::-webkit-scrollbar-thumb { background: var(--rb-line); }
|
||
.ringbrp-sheet ::-webkit-scrollbar-track { background: var(--rb-void); }
|
||
|
||
/* --- the utility register: every small label --- */
|
||
.rb-origin label, .rb-ages label, .rb-vital-label, .rb-dl,
|
||
.rb-table th, .rb-block, .rb-track-label, .rb-type, .rb-grid2 label,
|
||
.rb-strip-label {
|
||
font-family: var(--rb-body);
|
||
font-size: 10px;
|
||
font-weight: 700;
|
||
letter-spacing: .04em;
|
||
text-transform: uppercase;
|
||
color: var(--rb-muted);
|
||
}
|
||
|
||
/* --- data: tabular figures in the body face, not mono --- */
|
||
.rb-char input, .rb-hp input, .rb-big, .rb-armour input,
|
||
.rb-skill-val, .rb-dv, .rb-track-val, .rb-standing, .rb-char-x5 {
|
||
font-family: var(--rb-body);
|
||
font-variant-numeric: tabular-nums;
|
||
font-weight: 700;
|
||
}
|
||
|
||
/* ============================================================
|
||
Header — identity
|
||
============================================================ */
|
||
|
||
/* Two columns: who they are on the left, how they are on the right.
|
||
The vitals row is the widest thing in the right column, so the derived numbers
|
||
and the readied weapons stack underneath it and take their width from it. That
|
||
is what fills the header — it used to be one flex row with the vitals pinned to
|
||
the top, which left the whole area under them empty. It also puts damage
|
||
modifier and readied weapons next to hit points, where they are actually read. */
|
||
.rb-header {
|
||
display: grid;
|
||
grid-template-columns: minmax(320px, 1fr) minmax(0, 1.6fr);
|
||
gap: 10px 14px; align-items: start;
|
||
padding: 12px 14px 10px;
|
||
background: transparent;
|
||
border-bottom: 3px solid var(--rb-yellow);
|
||
}
|
||
.rb-ident { display: flex; gap: 14px; align-items: flex-start; min-width: 0; }
|
||
.rb-status { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
|
||
/* Inside the header these two are panels, not full-width bands, so they lose the
|
||
page-width padding and rule and gain a border of their own. */
|
||
.rb-status > .rb-derived,
|
||
.rb-status > .rb-weaponstrip {
|
||
padding: 6px 10px; border: 1px solid var(--rb-hairline);
|
||
/* width:0 + min-width:100% keeps these OUT of the auto track's max-content
|
||
measurement, so the column is sized by the vitals row and these stretch to
|
||
match it. Without it the readied-weapons line — which is as long as the
|
||
weapon names happen to be — sets the column width and crushes the portrait
|
||
and name into a 190px gutter. */
|
||
width: 0; min-width: 100%;
|
||
}
|
||
.rb-status > .rb-derived { gap: 14px; }
|
||
.rb-status > .rb-weaponstrip { gap: 12px; }
|
||
.rb-portrait {
|
||
width: 84px; height: 84px; flex: 0 0 84px; object-fit: cover;
|
||
border: 1px solid var(--rb-line); background: var(--rb-void);
|
||
}
|
||
.rb-headline { flex: 1 1 auto; display: flex; flex-direction: column; gap: 6px; min-width: 0; }
|
||
|
||
.rb-name {
|
||
font-family: var(--rb-display);
|
||
font-size: 18px;
|
||
letter-spacing: .02em;
|
||
color: var(--rb-white);
|
||
background: transparent;
|
||
border: none;
|
||
border-bottom: 1px solid var(--rb-hairline);
|
||
padding: 0 0 4px;
|
||
}
|
||
.rb-name:focus { border-bottom-color: var(--rb-yellow); outline: none; }
|
||
.rb-role { font-size: 12px; color: var(--rb-muted); background: transparent; border: none; }
|
||
|
||
.rb-origin, .rb-ages { display: flex; gap: 14px; flex-wrap: wrap; align-items: center; }
|
||
.rb-origin label, .rb-ages label { display: flex; align-items: center; gap: 5px; }
|
||
.rb-origin input, .rb-ages input { width: 92px; }
|
||
.rb-origin select { width: 116px; }
|
||
.rb-origin input, .rb-ages input, .rb-origin select { font-weight: 400; letter-spacing: 0;
|
||
text-transform: none; color: var(--rb-white); font-size: 12px;
|
||
}
|
||
.rb-ages input { width: 54px; }
|
||
.rb-style-fixed {
|
||
font-family: var(--rb-body); font-size: 10px; font-weight: 700; letter-spacing: .06em;
|
||
color: var(--rb-void); background: var(--rb-yellow);
|
||
padding: 3px 8px; text-transform: uppercase;
|
||
}
|
||
|
||
/* --- vitals: HP reads as one expression --- */
|
||
.rb-vitals { display: flex; gap: 8px; align-items: stretch; flex-wrap: wrap; }
|
||
.rb-vitals > div {
|
||
min-width: 78px; padding: 6px 10px; text-align: center;
|
||
background: var(--rb-void); border: 1px solid var(--rb-line);
|
||
display: flex; flex-direction: column; justify-content: center; gap: 2px;
|
||
}
|
||
.rb-vitals > .rb-hp {
|
||
display: grid;
|
||
grid-template-columns: auto auto auto;
|
||
grid-template-rows: auto auto;
|
||
align-items: baseline; justify-content: center; column-gap: 3px;
|
||
}
|
||
.rb-hp .rb-vital-label { grid-column: 1 / -1; }
|
||
.rb-hp input {
|
||
width: 42px; text-align: right; font-size: 24px;
|
||
background: transparent; border: none; padding: 0; color: var(--rb-white);
|
||
}
|
||
.rb-hp input:focus { outline: none; background: var(--rb-blue); }
|
||
.rb-slash { color: var(--rb-muted); font-size: 16px; }
|
||
.rb-max { font-size: 15px; color: var(--rb-muted); font-weight: 700; }
|
||
.rb-big { font-size: 24px; color: var(--rb-white); }
|
||
.rb-armour input {
|
||
width: 44px; text-align: center; font-size: 24px;
|
||
background: transparent; border: none; padding: 0; color: var(--rb-white);
|
||
}
|
||
.rb-grounded-hide {
|
||
display: block; margin-top: 2px;
|
||
font-family: var(--rb-body); font-size: 9px; font-weight: 700;
|
||
letter-spacing: .04em; text-transform: uppercase;
|
||
color: var(--rb-danger, #d9534f); white-space: nowrap;
|
||
}
|
||
.rb-wounded { border-color: var(--rb-danger) !important; }
|
||
.rb-wound-flag {
|
||
font-family: var(--rb-body); font-size: 10px; font-weight: 700;
|
||
color: var(--rb-danger); text-transform: uppercase; letter-spacing: .04em;
|
||
}
|
||
|
||
/* ============================================================
|
||
Characteristics — the roll target is the dominant number
|
||
============================================================ */
|
||
|
||
.rb-characteristics {
|
||
display: grid; grid-template-columns: repeat(8, 1fr); gap: 1px;
|
||
padding: 0; background: var(--rb-hairline);
|
||
border-top: 2px solid var(--rb-yellow);
|
||
border-bottom: 2px solid var(--rb-yellow);
|
||
}
|
||
.rb-char { text-align: center; background: var(--rb-deep); padding: 9px 2px 7px; }
|
||
.rb-char-label {
|
||
display: block; width: 100%;
|
||
font-family: var(--rb-body); font-size: 11px; font-weight: 700;
|
||
letter-spacing: .12em; color: var(--rb-line); cursor: pointer;
|
||
}
|
||
.rb-char:hover .rb-char-label { color: var(--rb-white); }
|
||
/* The characteristic itself. It was set smaller than the skill ratings beneath
|
||
it, so the eight numbers the whole system derives from read as a caption. */
|
||
.rb-char input {
|
||
width: 100%; text-align: center;
|
||
font-family: var(--rb-display); font-size: 26px; font-weight: 700;
|
||
line-height: 1.05; letter-spacing: -.01em;
|
||
background: transparent; border: none; padding: 2px 0 3px; color: var(--rb-white);
|
||
}
|
||
.rb-char input:focus { outline: 1px solid var(--rb-yellow); color: var(--rb-white); }
|
||
/* the ×5 chip — the actual roll target, so it keeps parity with the raw score */
|
||
.rb-char-x5 {
|
||
display: block; min-height: 30px; line-height: 30px;
|
||
font-size: 22px; color: var(--rb-yellow); cursor: pointer;
|
||
border-top: 1px solid var(--rb-hairline);
|
||
}
|
||
.rb-char-x5::before {
|
||
content: "×5 "; font-size: 10px; font-weight: 700;
|
||
color: var(--rb-muted); letter-spacing: .04em;
|
||
}
|
||
.rb-char-x5:hover { background: var(--rb-yellow); color: var(--rb-void); }
|
||
.rb-char-x5:hover::before { color: var(--rb-void); }
|
||
|
||
/* ============================================================
|
||
Derived strip
|
||
============================================================ */
|
||
|
||
.rb-derived {
|
||
display: flex; gap: 18px; align-items: center; flex-wrap: wrap;
|
||
padding: 7px 14px; border-bottom: 1px solid var(--rb-hairline);
|
||
}
|
||
.rb-dl { margin-right: 5px; }
|
||
.rb-dv { font-size: 13px; color: var(--rb-white); }
|
||
.rb-warn { color: var(--rb-danger); }
|
||
.rb-rolls { margin-left: auto; display: flex; gap: 6px; }
|
||
.rb-rolls button {
|
||
font-family: var(--rb-body); font-size: 11px; font-weight: 700; letter-spacing: .04em;
|
||
background: transparent; border: 1px solid var(--rb-yellow-dim);
|
||
color: var(--rb-yellow); padding: 4px 10px; border-radius: 0;
|
||
width: auto; line-height: 1.3; cursor: pointer; text-transform: uppercase;
|
||
}
|
||
.rb-rolls button:hover { background: var(--rb-yellow); border-color: var(--rb-yellow); color: var(--rb-void); }
|
||
|
||
/* ============================================================
|
||
Persistent weapon strip — the original sheet never hides weapons
|
||
============================================================ */
|
||
|
||
.rb-weaponstrip {
|
||
display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
|
||
padding: 6px 14px; border-bottom: 1px solid var(--rb-hairline);
|
||
background: var(--rb-panel);
|
||
}
|
||
.rb-strip-label { flex: 0 0 auto; }
|
||
.rb-strip-weapon { display: flex; align-items: baseline; gap: 7px; font-size: 12px; }
|
||
.rb-strip-weapon a { font-weight: 700; }
|
||
.rb-strip-dmg { font-weight: 700; font-variant-numeric: tabular-nums; color: var(--rb-white); }
|
||
.rb-strip-range, .rb-strip-ammo { font-size: 11px; color: var(--rb-muted); font-variant-numeric: tabular-nums; }
|
||
.rb-strip-empty { font-size: 12px; color: var(--rb-muted); font-style: italic; }
|
||
|
||
/* ============================================================
|
||
Tabs — solid active state, not a Material underline
|
||
============================================================ */
|
||
|
||
/* A RAIL, not a strip. Eight tabs across the top of an 820px sheet compressed to
|
||
11px type and were genuinely hard to read; down the side each one gets a whole
|
||
line to itself, so the type can be larger and the active tab can be a solid
|
||
block rather than a tint. */
|
||
|
||
.rb-main {
|
||
flex: 1 1 auto; min-height: 0;
|
||
display: flex; flex-direction: row; align-items: stretch;
|
||
}
|
||
|
||
.rb-tabs {
|
||
flex: 0 0 152px;
|
||
display: flex; flex-direction: column; padding: 8px 0 0;
|
||
background: var(--rb-void);
|
||
border-right: 1px solid var(--rb-line);
|
||
overflow-y: auto;
|
||
}
|
||
.rb-tabs .item {
|
||
display: flex; align-items: center; justify-content: space-between; gap: 6px;
|
||
font-family: var(--rb-display); font-weight: 700; font-size: 12px; letter-spacing: .05em;
|
||
text-transform: uppercase; color: var(--rb-muted); white-space: nowrap;
|
||
padding: 10px 10px 10px 13px;
|
||
border-left: 3px solid transparent;
|
||
border-bottom: 1px solid var(--rb-hairline);
|
||
}
|
||
.rb-tabs .item:hover { color: var(--rb-white); background: var(--rb-panel); }
|
||
.rb-tabs .item.active {
|
||
color: var(--rb-void); background: var(--rb-yellow);
|
||
border-left-color: var(--rb-white);
|
||
}
|
||
.rb-tab-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
|
||
.rb-tab-count {
|
||
flex: 0 0 auto; font-family: var(--rb-mono); font-size: 10px; font-weight: 700;
|
||
letter-spacing: 0; padding: 1px 5px; border-radius: 2px;
|
||
background: var(--rb-panel); color: var(--rb-white);
|
||
}
|
||
.rb-tabs .item.active .rb-tab-count { background: var(--rb-void); color: var(--rb-yellow); }
|
||
.rb-tab-count.rb-tab-bad { background: var(--rb-danger); color: var(--rb-void); }
|
||
.rb-tabs .item.active .rb-tab-count.rb-tab-bad { background: var(--rb-void); color: var(--rb-danger); }
|
||
|
||
.rb-body { flex: 1 1 auto; min-width: 0; overflow-y: auto; padding: 12px 14px 16px; }
|
||
|
||
/* Narrow windows cannot afford 132px of rail — fold it back to a strip. */
|
||
@media (max-width: 560px) {
|
||
.rb-main { flex-direction: column; }
|
||
.rb-tabs {
|
||
flex: 0 0 auto; flex-direction: row; overflow-x: auto; padding: 0 8px;
|
||
border-right: none; border-bottom: 1px solid var(--rb-line);
|
||
}
|
||
.rb-tabs .item {
|
||
border-left: none; border-bottom: 3px solid transparent; padding: 8px 11px;
|
||
}
|
||
.rb-tabs .item.active { border-bottom-color: var(--rb-white); }
|
||
}
|
||
|
||
/* ============================================================
|
||
Section heads — the book's rule treatment
|
||
============================================================ */
|
||
|
||
.rb-cat { margin-bottom: 14px; break-inside: avoid; }
|
||
.rb-cat-head {
|
||
display: flex; align-items: baseline; gap: 9px; margin: 0 0 4px;
|
||
font-family: var(--rb-display); font-size: 11px; letter-spacing: .08em;
|
||
text-transform: uppercase; color: var(--rb-white);
|
||
border: none;
|
||
border-top: 2px solid var(--rb-yellow);
|
||
border-bottom: 1px solid var(--rb-hairline);
|
||
padding: 5px 0 4px;
|
||
}
|
||
.rb-catbonus {
|
||
font-family: var(--rb-body); font-size: 11px; font-weight: 700;
|
||
font-variant-numeric: tabular-nums;
|
||
color: var(--rb-yellow); background: transparent;
|
||
border: 1px solid var(--rb-yellow-dim); padding: 0 5px;
|
||
}
|
||
.rb-add { margin-left: auto; font-size: 12px; }
|
||
.rb-add-wide {
|
||
display: block; text-align: center; padding: 6px; margin-top: 8px;
|
||
border: 1px dashed var(--rb-line);
|
||
font-family: var(--rb-body); font-size: 10px; font-weight: 700;
|
||
letter-spacing: .04em; text-transform: uppercase;
|
||
}
|
||
|
||
/* ============================================================
|
||
Skills — two columns, the original sheet's search pattern
|
||
============================================================ */
|
||
|
||
.rb-body .tab[data-tab="skills"].active {
|
||
display: block;
|
||
/* Driven by the space actually available rather than by window width. The rail
|
||
takes 152px the body used to have, so a width-based breakpoint measured the
|
||
wrong box and dropped to one column while there was still room for two. */
|
||
columns: 300px 2;
|
||
column-gap: 22px;
|
||
column-fill: balance;
|
||
}
|
||
.rb-skills { list-style: none; margin: 0; padding: 0; }
|
||
/* Seven columns: tick, icon, name, value, bands, edit, delete. The NPC sheet's rows
|
||
carry four children, not seven, so it gets its own template below — sharing this one
|
||
put the name in a 13px column and the value in a 20px one, and the whole list
|
||
overlapped itself. Nobody saw it because nobody had ever opened an NPC sheet. */
|
||
.rb-skill {
|
||
display: grid; grid-template-columns: 13px 20px minmax(0,1fr) 44px 104px 15px 15px;
|
||
gap: 5px; align-items: center; min-height: 26px; padding: 0;
|
||
border-bottom: 1px solid var(--rb-hairline);
|
||
}
|
||
/* name · value · edit · delete */
|
||
.rb-npc .rb-skill {
|
||
grid-template-columns: minmax(0,1fr) 46px 15px 15px;
|
||
}
|
||
.rb-skill:hover { background: var(--rb-blue); }
|
||
.rb-tick { width: 12px; height: 12px; border: 1px solid var(--rb-muted); display: inline-block; }
|
||
.rb-tick.on { background: var(--rb-yellow); border-color: var(--rb-yellow); }
|
||
.rb-skill-name { font-size: 13px; color: var(--rb-white); }
|
||
.rb-skill-name:hover { color: var(--rb-yellow); }
|
||
/* passive datum, therefore white. The NAME carries the roll affordance. */
|
||
.rb-skill-val { text-align: right; font-size: 13px; color: var(--rb-white); }
|
||
.rb-skill-bands {
|
||
font-family: var(--rb-mono); font-size: 9.5px; color: var(--rb-muted);
|
||
text-align: right; letter-spacing: -.03em;
|
||
white-space: nowrap; overflow: hidden;
|
||
}
|
||
|
||
/* roll affordance: underline whatever rolls */
|
||
.ringbrp-sheet a[data-action^="roll"] {
|
||
text-decoration: underline;
|
||
text-decoration-color: var(--rb-yellow-dim);
|
||
text-underline-offset: 2px;
|
||
}
|
||
.rb-char-x5, .rb-char-label { text-decoration: none !important; }
|
||
|
||
/* ============================================================
|
||
Tables & lists
|
||
============================================================ */
|
||
|
||
.rb-table { width: 100%; border-collapse: collapse; font-size: 13px; margin-bottom: 12px; }
|
||
.rb-table th { text-align: left; border-bottom: 1px solid var(--rb-line); padding: 4px 5px; }
|
||
.rb-table td { padding: 5px; border-bottom: 1px solid var(--rb-hairline); }
|
||
.rb-table tbody tr:hover { background: var(--rb-blue); }
|
||
.rb-actions { text-align: right; white-space: nowrap; }
|
||
.rb-list { list-style: none; margin: 0 0 12px; padding: 0; font-size: 13px; }
|
||
.rb-list li {
|
||
display: flex; align-items: center; gap: 10px; min-height: 26px;
|
||
border-bottom: 1px solid var(--rb-hairline);
|
||
}
|
||
.rb-strong { font-weight: 700; color: var(--rb-white); }
|
||
.rb-dim { color: var(--rb-muted); font-size: 12px; }
|
||
.rb-empty { color: var(--rb-muted); font-style: italic; text-align: center; padding: 26px; }
|
||
/* `.ringbrp-sheet a` is more specific than a lone class, so the unequipped state was
|
||
being painted white and read as "on". Both toggles — armour and weapons — depend
|
||
on the off state actually looking off. */
|
||
.ringbrp-sheet .rb-equip { color: var(--rb-muted); }
|
||
.ringbrp-sheet .rb-equip:hover { color: var(--rb-white); }
|
||
.ringbrp-sheet .rb-equip.on { color: var(--rb-yellow); }
|
||
|
||
/* ============================================================
|
||
JOURNALS — the department's own paper
|
||
============================================================
|
||
Twelve pages of rulebook and a player primer were rendering as Foundry's default
|
||
parchment, which is the one place in the system that did not look like the system.
|
||
Scoped to .ringbrp-journal, applied by a hook to this system's entries only, so
|
||
other modules' journals are left alone. */
|
||
|
||
.ringbrp-journal .window-content,
|
||
.ringbrp-journal .journal-entry-content,
|
||
.ringbrp-journal .journal-entry-pages { background: var(--rb-deep); }
|
||
|
||
/* The contents rail: this is how a player moves through ten pages. */
|
||
.ringbrp-journal .journal-sidebar {
|
||
background: var(--rb-void); border-right: 1px solid var(--rb-line);
|
||
}
|
||
.ringbrp-journal .journal-sidebar .toc li.page {
|
||
font-family: var(--rb-display); font-size: 10px; letter-spacing: .05em;
|
||
text-transform: uppercase; color: var(--rb-muted);
|
||
border-bottom: 1px solid var(--rb-hairline);
|
||
}
|
||
.ringbrp-journal .journal-sidebar .toc li.page:hover { color: var(--rb-white); }
|
||
.ringbrp-journal .journal-sidebar .toc li.page.active,
|
||
.ringbrp-journal .journal-sidebar .toc li.page.readied {
|
||
color: var(--rb-void); background: var(--rb-yellow);
|
||
}
|
||
.ringbrp-journal .journal-header .title {
|
||
font-family: var(--rb-display); color: var(--rb-yellow);
|
||
background: transparent; border: none;
|
||
}
|
||
|
||
/* A page. v14 puts the prose straight inside article.journal-entry-page — there is no
|
||
.journal-page-content wrapper, which is why the first version of this styled nothing. */
|
||
.ringbrp-journal .journal-entry-page {
|
||
background: var(--rb-deep);
|
||
color: var(--rb-white);
|
||
font-family: var(--rb-body);
|
||
font-size: 14px;
|
||
line-height: 1.55;
|
||
padding: 4px 18px 28px;
|
||
}
|
||
|
||
.ringbrp-journal .journal-entry-page h1 {
|
||
font-family: var(--rb-display); font-size: 19px; letter-spacing: .06em;
|
||
text-transform: uppercase; color: var(--rb-yellow);
|
||
border: none; border-bottom: 2px solid var(--rb-yellow); padding-bottom: 8px;
|
||
margin: 0 0 18px;
|
||
}
|
||
.ringbrp-journal .journal-entry-page h2 {
|
||
font-family: var(--rb-display); font-size: 13px; letter-spacing: .1em;
|
||
text-transform: uppercase; color: var(--rb-yellow);
|
||
border: none; border-bottom: 1px solid var(--rb-hairline); padding-bottom: 5px;
|
||
margin: 26px 0 12px;
|
||
}
|
||
.ringbrp-journal .journal-entry-page h3 {
|
||
font-family: var(--rb-display); font-size: 11px; letter-spacing: .09em;
|
||
text-transform: uppercase; color: var(--rb-white); border: none; margin: 20px 0 8px;
|
||
}
|
||
.ringbrp-journal .journal-entry-page p { margin: 0 0 12px; }
|
||
.ringbrp-journal .journal-entry-page strong { color: var(--rb-yellow); font-weight: 700; }
|
||
.ringbrp-journal .journal-entry-page em { color: var(--rb-muted); }
|
||
.ringbrp-journal .journal-entry-page a { color: var(--rb-yellow); }
|
||
|
||
.ringbrp-journal .journal-entry-page ul,
|
||
.ringbrp-journal .journal-entry-page ol { margin: 0 0 14px; padding-left: 22px; }
|
||
.ringbrp-journal .journal-entry-page li { margin-bottom: 5px; }
|
||
.ringbrp-journal .journal-entry-page ul { list-style: none; padding-left: 16px; }
|
||
.ringbrp-journal .journal-entry-page ul > li:before {
|
||
content: "\25aa"; color: var(--rb-yellow); margin-left: -14px; margin-right: 8px;
|
||
}
|
||
.ringbrp-journal .journal-entry-page ol > li::marker { color: var(--rb-yellow); font-weight: 700; }
|
||
|
||
.ringbrp-journal .journal-entry-page table {
|
||
width: 100%; border-collapse: collapse; margin: 0 0 16px;
|
||
background: var(--rb-void); border: 1px solid var(--rb-line);
|
||
}
|
||
.ringbrp-journal .journal-entry-page th {
|
||
font-family: var(--rb-display); font-size: 10px; letter-spacing: .08em;
|
||
text-transform: uppercase; text-align: left; color: var(--rb-void);
|
||
background: var(--rb-yellow); padding: 6px 9px; border: none;
|
||
}
|
||
.ringbrp-journal .journal-entry-page td {
|
||
padding: 6px 9px; border-top: 1px solid var(--rb-hairline); vertical-align: top;
|
||
}
|
||
.ringbrp-journal .journal-entry-page tbody tr:nth-child(even) { background: var(--rb-panel); }
|
||
|
||
/* Read-aloud: the one thing a GM says in somebody else's voice. */
|
||
.ringbrp-journal .rb-readaloud {
|
||
margin: 0 0 18px; padding: 12px 16px;
|
||
background: var(--rb-void);
|
||
border: none; border-left: 3px solid var(--rb-yellow);
|
||
color: var(--rb-white); font-size: 15px; line-height: 1.6;
|
||
}
|
||
.ringbrp-journal .rb-readaloud strong,
|
||
.ringbrp-journal .rb-readaloud em { color: var(--rb-yellow); }
|
||
|
||
/* Scenario plates. Full bleed to the column, hairline, no caption — the paragraph
|
||
under the picture is the caption, and a GM reading at a table does not need two. */
|
||
.ringbrp-journal .rb-plate {
|
||
margin: 0 0 18px; padding: 0;
|
||
border: 1px solid var(--rb-hairline);
|
||
background: var(--rb-void);
|
||
line-height: 0;
|
||
}
|
||
.ringbrp-journal .rb-plate img {
|
||
display: block; width: 100%; height: auto; border: none; margin: 0;
|
||
}
|
||
|
||
/* Maps and diagrams are typed, not drawn. */
|
||
.ringbrp-journal .rb-map {
|
||
background: var(--rb-void); border: 1px solid var(--rb-line);
|
||
color: var(--rb-muted); font-family: var(--rb-mono); font-size: 11px;
|
||
line-height: 1.45; padding: 12px 14px; margin: 0 0 16px;
|
||
overflow-x: auto; white-space: pre;
|
||
}
|
||
|
||
/* A departmental form: the stamped block a primer page opens with. */
|
||
.ringbrp-journal .rb-form {
|
||
background: var(--rb-void); border: 1px solid var(--rb-line);
|
||
border-top: 3px solid var(--rb-yellow);
|
||
padding: 12px 14px; margin: 0 0 20px;
|
||
font-family: var(--rb-mono); font-size: 11px; line-height: 1.7;
|
||
color: var(--rb-muted); text-transform: uppercase; letter-spacing: .04em;
|
||
}
|
||
.ringbrp-journal .rb-form b { color: var(--rb-white); font-weight: 700; }
|
||
.ringbrp-journal .rb-stamp {
|
||
display: inline-block; border: 2px solid var(--rb-danger); color: var(--rb-danger);
|
||
font-family: var(--rb-display); font-size: 11px; letter-spacing: .14em;
|
||
text-transform: uppercase; padding: 4px 10px; transform: rotate(-2deg);
|
||
margin: 4px 0 14px;
|
||
}
|
||
/* The line a page lands on. */
|
||
.ringbrp-journal .rb-closer {
|
||
font-family: var(--rb-display); font-size: 13px; letter-spacing: .05em;
|
||
color: var(--rb-yellow); text-align: center;
|
||
border-top: 1px solid var(--rb-hairline); padding-top: 16px; margin-top: 22px;
|
||
}
|
||
.ringbrp-journal .rb-two { columns: 260px 2; column-gap: 26px; }
|
||
.ringbrp-journal .rb-two > * { break-inside: avoid; }
|
||
|
||
/* The cheat sheet: a card per rule, so it can be skimmed under pressure. */
|
||
.ringbrp-journal .rb-cards {
|
||
display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
||
gap: 12px; margin: 0 0 18px;
|
||
}
|
||
.ringbrp-journal .rb-card {
|
||
background: var(--rb-void); border: 1px solid var(--rb-line);
|
||
border-left: 3px solid var(--rb-yellow); padding: 10px 12px;
|
||
}
|
||
.ringbrp-journal .rb-card h4 {
|
||
font-family: var(--rb-display); font-size: 10px; letter-spacing: .09em;
|
||
text-transform: uppercase; color: var(--rb-yellow); margin: 0 0 6px; border: none;
|
||
}
|
||
.ringbrp-journal .rb-card p { margin: 0 0 6px; font-size: 13px; }
|
||
.ringbrp-journal .rb-card p:last-child { margin-bottom: 0; }
|
||
.ringbrp-journal .rb-big-number {
|
||
font-family: var(--rb-display); font-size: 22px; color: var(--rb-white);
|
||
line-height: 1.15; display: block; margin-bottom: 6px;
|
||
}
|
||
|
||
/* ============================================================
|
||
Shields — armour with a switch, so the switch has to be visible
|
||
============================================================ */
|
||
|
||
.ringbrp-sheet .rb-raise { color: var(--rb-muted); margin-left: 2px; }
|
||
.ringbrp-sheet .rb-raise:hover { color: var(--rb-white); }
|
||
.ringbrp-sheet .rb-raise.on { color: var(--rb-yellow); }
|
||
.rb-shield-up { background: rgba(255, 214, 0, .07); }
|
||
.rb-shield-up .rb-strong { color: var(--rb-yellow); }
|
||
.rb-shield-state {
|
||
font-family: var(--rb-display); font-size: 9px; letter-spacing: .08em;
|
||
text-transform: uppercase; color: var(--rb-muted);
|
||
border: 1px solid var(--rb-hairline); padding: 0 5px;
|
||
}
|
||
.rb-shield-up .rb-shield-state { color: var(--rb-void); background: var(--rb-yellow); border-color: var(--rb-yellow); }
|
||
.rb-shield-wear { font-family: var(--rb-mono); font-size: 10px; }
|
||
.rb-shield-broken { opacity: .55; }
|
||
.rb-shield-broken .rb-shield-state { color: var(--rb-danger); border-color: var(--rb-danger); }
|
||
.rb-cbtn-shield { border-color: var(--rb-yellow-dim); color: var(--rb-yellow); }
|
||
|
||
/* ============================================================
|
||
Coherence, promoted to the vitals — it is a survival number
|
||
============================================================ */
|
||
|
||
.rb-vital-coh { position: relative; }
|
||
.rb-coh-row { display: flex; align-items: baseline; justify-content: center; gap: 2px; }
|
||
.rb-vital-coh .rb-cohbtn {
|
||
font-size: 15px; line-height: 1; padding: 0 4px; color: var(--rb-muted);
|
||
}
|
||
.rb-vital-coh .rb-cohbtn:hover { color: var(--rb-yellow); }
|
||
.rb-vital-coh .rb-cohband {
|
||
font-family: var(--rb-display); font-size: 9px; letter-spacing: .08em;
|
||
text-transform: uppercase; color: var(--rb-muted);
|
||
}
|
||
/* Coherence going is how this game kills you slowly, so the box says so. */
|
||
.rb-vital-coh.rb-coh-loose { border-color: var(--rb-yellow-dim); }
|
||
.rb-vital-coh.rb-coh-adrift { border-color: var(--rb-yellow); }
|
||
.rb-vital-coh.rb-coh-adrift .rb-cohband { color: var(--rb-yellow); }
|
||
.rb-vital-coh.rb-coh-unmoored,
|
||
.rb-vital-coh.rb-coh-displaced { border-color: var(--rb-danger); }
|
||
.rb-vital-coh.rb-coh-unmoored .rb-big,
|
||
.rb-vital-coh.rb-coh-displaced .rb-big,
|
||
.rb-vital-coh.rb-coh-unmoored .rb-cohband,
|
||
.rb-vital-coh.rb-coh-displaced .rb-cohband { color: var(--rb-danger); }
|
||
|
||
.rb-armour-range {
|
||
font-family: var(--rb-mono); font-size: 9px; color: var(--rb-muted);
|
||
}
|
||
|
||
/* ============================================================
|
||
Armour, per location — the number and the thing providing it
|
||
============================================================ */
|
||
|
||
.rb-col-ap { white-space: nowrap; text-align: right; }
|
||
.rb-ap-num {
|
||
font-weight: 700; font-variant-numeric: tabular-nums; color: var(--rb-white);
|
||
}
|
||
.rb-ap-from { display: inline-flex; gap: 4px; margin-left: 7px; flex-wrap: wrap; }
|
||
.rb-ap-piece {
|
||
font-size: 9px; letter-spacing: .02em; color: var(--rb-yellow);
|
||
border: 1px solid var(--rb-yellow-dim); padding: 0 4px; border-radius: 2px;
|
||
}
|
||
.rb-ap-piece b { color: var(--rb-white); font-weight: 700; }
|
||
.rb-ap-bare {
|
||
font-size: 9px; font-style: italic; color: var(--rb-line); margin-left: 7px;
|
||
}
|
||
/* The compact table IS the combat tab's, and the piece names are the point of the
|
||
request — so they stay. They wrap under the number when the column is narrow. */
|
||
.rb-loctable-compact .rb-col-ap { white-space: normal; }
|
||
.rb-loctable-compact .rb-ap-from { margin-left: 5px; }
|
||
.rb-loctable-compact .rb-ap-piece { font-size: 8px; }
|
||
|
||
/* ============================================================
|
||
Weapons — the first thing on the combat tab, and it should look it
|
||
============================================================ */
|
||
|
||
.rb-ready-hint { margin: 0 0 8px; }
|
||
.rb-weapontable .rb-col-ready { width: 40px; text-align: center; }
|
||
.rb-weapontable td { vertical-align: middle; }
|
||
.rb-weapontable .rb-equip { font-size: 15px; }
|
||
.rb-reload { margin-left: 4px; font-size: 11px; color: var(--rb-muted); cursor: pointer; }
|
||
.rb-reload:hover { color: var(--rb-yellow); }
|
||
.rb-weapon-icon {
|
||
width: 40px; height: 40px; margin-right: 9px;
|
||
border: 1px solid var(--rb-hairline); background: var(--rb-void);
|
||
vertical-align: middle;
|
||
}
|
||
.rb-weapon-name {
|
||
font-family: var(--rb-display); font-size: 15px; font-weight: 700;
|
||
letter-spacing: .02em; vertical-align: middle;
|
||
}
|
||
.rb-weapon-dmg { font-size: 15px; font-weight: 700; font-variant-numeric: tabular-nums; }
|
||
/* A readied weapon is marked in the table too, so the strip and the list agree. */
|
||
.rb-wrow-ready { background: rgba(255, 214, 0, .06); }
|
||
.rb-wrow-ready .rb-weapon-icon { border-color: var(--rb-yellow-dim); }
|
||
.rb-wrow-ready .rb-weapon-name { color: var(--rb-yellow); }
|
||
|
||
/* ============================================================
|
||
The figure, small — every location and the armour over it
|
||
============================================================ */
|
||
|
||
/* The vitals row is a flex of equal-height boxes; this one must not be allowed to
|
||
set that height. .rb-body-svg is declared further down the file with max-width
|
||
180px, so the mini needs the compound selector to win rather than a later one. */
|
||
.rb-minibody {
|
||
display: flex; align-items: center; gap: 9px;
|
||
padding: 5px 9px; border: 1px solid var(--rb-line); background: var(--rb-void);
|
||
flex: 0 0 auto;
|
||
}
|
||
.rb-vitals > .rb-minibody { min-width: 0; text-align: left; flex-direction: row; }
|
||
.rb-body-svg.rb-body-mini {
|
||
width: 34px; max-width: 34px; height: auto; flex: 0 0 auto;
|
||
}
|
||
.rb-minilocs {
|
||
list-style: none; margin: 0; padding: 0;
|
||
display: grid; grid-template-columns: repeat(2, auto); gap: 0 12px;
|
||
font-family: var(--rb-mono); font-size: 9px; line-height: 1.45;
|
||
}
|
||
.rb-miniloc { display: flex; gap: 5px; align-items: baseline; white-space: nowrap; }
|
||
.rb-miniloc-name { color: var(--rb-muted); min-width: 52px; }
|
||
.rb-miniloc-hp { color: var(--rb-white); font-variant-numeric: tabular-nums; }
|
||
.rb-miniloc-ap {
|
||
color: var(--rb-yellow); font-weight: 700; min-width: 12px; text-align: right;
|
||
}
|
||
.rb-miniloc-noap { color: var(--rb-line); }
|
||
.rb-miniloc-grazed .rb-miniloc-hp { color: var(--rb-yellow); }
|
||
.rb-miniloc-hurt .rb-miniloc-hp { color: var(--rb-danger); }
|
||
.rb-miniloc-disabled .rb-miniloc-name,
|
||
.rb-miniloc-destroyed .rb-miniloc-name { color: var(--rb-danger); text-decoration: line-through; }
|
||
|
||
/* Armour reads on the figure itself, at any size. */
|
||
.rb-part-armoured { stroke-width: 2.5px; }
|
||
|
||
/* Anatomy tab: the same figure, beside the full table. */
|
||
.rb-anatblock { display: grid; grid-template-columns: minmax(0, 200px) minmax(0, 1fr); gap: 18px; align-items: start; }
|
||
.rb-anatside { min-width: 0; }
|
||
@media (max-width: 620px) { .rb-anatblock { grid-template-columns: 1fr; } }
|
||
.rb-block { margin: 12px 0 4px; border-top: 1px solid var(--rb-hairline); padding-top: 7px; }
|
||
.rb-wounds li { border-left: 3px solid var(--rb-danger); padding-left: 8px; }
|
||
|
||
/* ============================================================
|
||
Expedition
|
||
============================================================ */
|
||
|
||
.rb-tracks { display: flex; gap: 8px; padding: 12px 14px; border-bottom: 1px solid var(--rb-hairline); }
|
||
.rb-track {
|
||
flex: 1; display: flex; align-items: center; justify-content: center; gap: 9px;
|
||
background: var(--rb-void); border: 1px solid var(--rb-line); padding: 9px;
|
||
}
|
||
.rb-track-val { font-size: 26px; color: var(--rb-white); min-width: 32px; text-align: center; }
|
||
.rb-track-max { font-size: 12px; color: var(--rb-muted); font-weight: 700; }
|
||
.rb-tracks.rb-crisis .rb-track-val { color: var(--rb-danger); }
|
||
.rb-crisis-note { color: var(--rb-danger); text-align: center; font-size: 13px; margin: 7px 14px; }
|
||
.rb-bigbutton {
|
||
width: 100%; padding: 10px; margin-bottom: 12px;
|
||
font-family: var(--rb-body); font-weight: 700; font-size: 11px; letter-spacing: .08em;
|
||
text-transform: uppercase; background: transparent;
|
||
border: 2px solid var(--rb-yellow); color: var(--rb-yellow); border-radius: 0; cursor: pointer;
|
||
}
|
||
.rb-bigbutton:hover { background: var(--rb-yellow); color: var(--rb-void); }
|
||
.rb-table tr.rb-done td { opacity: .45; }
|
||
.rb-table tr.rb-current td { box-shadow: inset 3px 0 0 var(--rb-yellow); }
|
||
.rb-standing { font-size: 13px; color: var(--rb-white); }
|
||
.rb-objective { font-size: 12px; color: var(--rb-muted); font-style: italic; width: 100%; }
|
||
|
||
/* ============================================================
|
||
Item sheet
|
||
============================================================ */
|
||
|
||
.rb-item-header {
|
||
display: flex; gap: 12px; align-items: center; padding: 12px 14px;
|
||
border-bottom: 3px solid var(--rb-yellow); background: transparent;
|
||
}
|
||
.rb-item-img { width: 52px; height: 52px; border: 1px solid var(--rb-line); }
|
||
.rb-grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 12px; }
|
||
.rb-grid2 label { display: flex; flex-direction: column; gap: 3px; }
|
||
.rb-grid2 label input, .rb-grid2 label select {
|
||
font-weight: 400; letter-spacing: 0; text-transform: none; color: var(--rb-white);
|
||
}
|
||
.rb-check { flex-direction: row !important; align-items: center; gap: 7px; }
|
||
.rb-hint { font-size: 12px; color: var(--rb-muted); margin-top: 10px; }
|
||
.rb-fn { border: 1px solid var(--rb-line); padding: 8px 10px; margin-bottom: 10px; }
|
||
.rb-fn legend {
|
||
font-family: var(--rb-body); font-size: 10px; font-weight: 700; letter-spacing: .06em;
|
||
text-transform: uppercase; color: var(--rb-yellow); padding: 0 5px;
|
||
}
|
||
|
||
/* ============================================================
|
||
Chat — flat card
|
||
============================================================ */
|
||
|
||
.ringbrp-chat {
|
||
background: var(--rb-void);
|
||
border: 1px solid var(--rb-line);
|
||
box-shadow: inset 0 0 0 1px var(--rb-yellow-dim);
|
||
padding: 10px 12px;
|
||
color: var(--rb-white);
|
||
font-family: var(--rb-body);
|
||
}
|
||
.rb-chat-title {
|
||
font-family: var(--rb-display); font-size: 11px; letter-spacing: .08em;
|
||
text-transform: uppercase; color: var(--rb-yellow); margin: 0 0 7px;
|
||
border: none; border-bottom: 1px solid var(--rb-hairline); padding-bottom: 6px;
|
||
}
|
||
.rb-chat-line {
|
||
font-size: 12px; color: var(--rb-muted); font-variant-numeric: tabular-nums;
|
||
display: flex; gap: 7px; align-items: baseline; flex-wrap: wrap;
|
||
}
|
||
.rb-chat-eff { color: var(--rb-white); font-weight: 700; }
|
||
.rb-chat-flavour { list-style: none; margin: 7px 0 0; padding: 0; font-size: 12px; color: var(--rb-muted); }
|
||
.rb-chat-flavour li:before { content: "› "; color: var(--rb-yellow); }
|
||
.rb-chat-result { display: flex; align-items: baseline; gap: 12px; margin-top: 8px; }
|
||
.rb-chat-roll { font-size: 32px; font-weight: 700; line-height: 1; font-variant-numeric: tabular-nums; }
|
||
.rb-chat-level {
|
||
font-family: var(--rb-display); font-size: 12px; letter-spacing: .12em; text-transform: uppercase;
|
||
}
|
||
.rb-chat-bands {
|
||
display: flex; gap: 14px; font-family: var(--rb-mono); font-size: 10px;
|
||
color: var(--rb-muted); margin-top: 7px;
|
||
border-top: 1px solid var(--rb-hairline); padding-top: 6px;
|
||
}
|
||
.rb-roll.rb-critical .rb-chat-level, .rb-roll.rb-critical .rb-chat-roll { color: var(--rb-yellow); }
|
||
.rb-roll.rb-special .rb-chat-level, .rb-roll.rb-special .rb-chat-roll { color: var(--rb-good); }
|
||
.rb-roll.rb-success .rb-chat-level { color: var(--rb-good); }
|
||
.rb-roll.rb-failure .rb-chat-level { color: var(--rb-muted); }
|
||
.rb-roll.rb-fumble .rb-chat-level, .rb-roll.rb-fumble .rb-chat-roll { color: var(--rb-danger); }
|
||
.rb-wound-title {
|
||
font-family: var(--rb-display); font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
|
||
color: var(--rb-danger); margin: 8px 0 4px; border: none;
|
||
}
|
||
.rb-wound-text { font-size: 13px; margin: 0 0 5px; }
|
||
.rb-wound-loss { font-size: 13px; color: var(--rb-yellow); margin: 0 0 5px; font-weight: 700; }
|
||
.rb-wound-stamina { font-size: 11px; color: var(--rb-muted); font-style: italic; margin: 0; }
|
||
.rb-dialog .notes { font-size: 12px; color: var(--rb-muted); }
|
||
|
||
/* Damage. This card used to be posted as a bare Roll and wore Foundry's stock
|
||
dice styling — grey boxes on a white panel, in the middle of a navy sheet. */
|
||
.rb-chat-formula { font-family: var(--rb-mono); color: var(--rb-white); }
|
||
.rb-chat-mod { font-size: 11px; color: var(--rb-muted); }
|
||
.rb-damage-result { align-items: baseline; gap: 9px; }
|
||
.rb-damage-total {
|
||
font-size: 34px; font-weight: 700; line-height: 1; color: var(--rb-yellow);
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
.rb-damage-unit {
|
||
font-family: var(--rb-display); font-size: 11px; letter-spacing: .12em;
|
||
text-transform: uppercase; color: var(--rb-muted);
|
||
}
|
||
.rb-damage-wound {
|
||
margin-left: auto; font-family: var(--rb-mono); font-size: 10px;
|
||
text-transform: uppercase; letter-spacing: .06em; color: var(--rb-muted);
|
||
border: 1px solid var(--rb-hairline); padding: 1px 6px;
|
||
}
|
||
.rb-damage-dice { gap: 6px; }
|
||
.rb-damage-dice span {
|
||
min-width: 17px; text-align: center; color: var(--rb-white);
|
||
border: 1px solid var(--rb-hairline); padding: 1px 0;
|
||
}
|
||
.rb-damage.rb-critical .rb-chat-title { color: var(--rb-yellow); }
|
||
.rb-damage.rb-critical .rb-damage-total { color: var(--rb-white); }
|
||
|
||
/* What the pack is doing to the shot without being asked. */
|
||
.rb-dialog-kit {
|
||
margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--rb-hairline);
|
||
}
|
||
.rb-kit-head {
|
||
font-family: var(--rb-display); font-size: 10px; letter-spacing: .1em;
|
||
text-transform: uppercase; color: var(--rb-yellow);
|
||
}
|
||
.rb-dialog-kit ul { list-style: none; margin: 4px 0 0; padding: 0; font-size: 12px; color: var(--rb-muted); }
|
||
.rb-dialog-kit li:before { content: "› "; color: var(--rb-yellow); }
|
||
.rb-fire-group .notes { margin: 3px 0 0; font-style: italic; }
|
||
|
||
/* ============================================================
|
||
ITEM SHEET — the statline, after the 1984 weapons table
|
||
============================================================ */
|
||
|
||
.rb-item-ident { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1 1 auto; }
|
||
.rb-item .rb-name { font-size: 18px; }
|
||
|
||
.rb-statline {
|
||
display: grid;
|
||
grid-auto-flow: column;
|
||
grid-auto-columns: minmax(0, 1fr);
|
||
background: var(--rb-void);
|
||
border-top: 2px solid var(--rb-yellow);
|
||
border-bottom: 1px solid var(--rb-line);
|
||
}
|
||
.rb-stat {
|
||
min-width: 0; padding: 6px 10px;
|
||
border-right: 1px solid var(--rb-line);
|
||
display: flex; flex-direction: column; gap: 2px;
|
||
}
|
||
.rb-stat:last-child { border-right: none; }
|
||
.rb-stat-wide { grid-column: span 3; }
|
||
/* the actionable datum dominates — the mistake corrected on the character sheet */
|
||
.rb-stat-primary { grid-column: span 2; }
|
||
.rb-stat-primary .rb-stat-value { font-size: 22px; line-height: 1.05; color: var(--rb-yellow); }
|
||
.rb-stat-label {
|
||
font-family: var(--rb-body); font-size: 10px; font-weight: 700;
|
||
letter-spacing: .04em; text-transform: uppercase; color: var(--rb-muted);
|
||
}
|
||
.rb-stat-value {
|
||
font-family: var(--rb-body); font-size: 15px; font-weight: 700;
|
||
font-variant-numeric: tabular-nums; color: var(--rb-white);
|
||
}
|
||
.rb-stat-big { font-size: 20px; line-height: 1.1; color: var(--rb-white); }
|
||
.rb-stat-of { font-size: 13px; color: var(--rb-muted); }
|
||
.rb-stat-mono { font-family: var(--rb-mono); font-size: 12px; font-weight: 400; color: var(--rb-muted); }
|
||
.rb-stat-question { font-size: 13px; font-weight: 400; font-style: italic; color: var(--rb-white); }
|
||
.rb-stat-roll { color: var(--rb-yellow); cursor: pointer;
|
||
text-decoration: underline; text-decoration-color: var(--rb-yellow-dim); text-underline-offset: 3px; }
|
||
.rb-stat-roll:hover { color: #fff; }
|
||
.rb-statline-locked { box-shadow: inset 3px 0 0 var(--rb-danger); }
|
||
|
||
.rb-grid3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px 12px; }
|
||
.rb-grid3 label {
|
||
display: flex; flex-direction: column; gap: 3px;
|
||
font-family: var(--rb-body); font-size: 10px; font-weight: 700;
|
||
letter-spacing: .04em; text-transform: uppercase; color: var(--rb-muted);
|
||
}
|
||
.rb-grid3 label input, .rb-grid3 label select {
|
||
font-weight: 400; letter-spacing: 0; text-transform: none; color: var(--rb-white);
|
||
}
|
||
.rb-wide { width: 100%; }
|
||
.rb-hint-warn { color: var(--rb-danger); }
|
||
.rb-fnbody { margin-bottom: 12px; }
|
||
.rb-fn-effect {
|
||
font-size: 12px; color: var(--rb-muted); margin: 0 0 8px;
|
||
border-left: 2px solid var(--rb-line); padding-left: 9px;
|
||
}
|
||
.rb-locked-chip {
|
||
font-family: var(--rb-body); font-size: 10px; font-weight: 700; letter-spacing: .04em;
|
||
text-transform: uppercase; color: var(--rb-void); background: var(--rb-danger); padding: 1px 6px;
|
||
}
|
||
.rb-tags { display: flex; flex-wrap: wrap; gap: 5px; margin: 0; }
|
||
.rb-tag {
|
||
font-family: var(--rb-body); font-size: 11px; font-weight: 700; color: var(--rb-white);
|
||
border: 1px solid var(--rb-line); padding: 1px 6px;
|
||
}
|
||
.rb-taboo { color: var(--rb-danger); font-size: 12px; }
|
||
.rb-desire { color: var(--rb-good); font-size: 12px; }
|
||
.rb-offerform { color: var(--rb-white); font-size: 12px; }
|
||
.rb-standing-chip {
|
||
font-family: var(--rb-body); font-size: 11px; font-weight: 700;
|
||
color: var(--rb-void); background: var(--rb-yellow); padding: 0 6px; min-width: 26px; text-align: center;
|
||
}
|
||
|
||
/* --- research steps --- */
|
||
.rb-steps { list-style: none; margin: 0 0 12px; padding: 0; }
|
||
.rb-step {
|
||
display: grid; grid-template-columns: 26px 1fr auto; gap: 9px; align-items: baseline;
|
||
padding: 7px 0; border-bottom: 1px solid var(--rb-hairline);
|
||
}
|
||
.rb-step-n {
|
||
font-family: var(--rb-body); font-size: 12px; font-weight: 700; text-align: center;
|
||
color: var(--rb-muted); border: 1px solid var(--rb-line); line-height: 20px;
|
||
}
|
||
.rb-step-current { box-shadow: inset 3px 0 0 var(--rb-yellow); padding-left: 8px; }
|
||
.rb-step-current .rb-step-n { color: var(--rb-void); background: var(--rb-yellow); border-color: var(--rb-yellow); }
|
||
.rb-step-done { opacity: .5; }
|
||
.rb-step-body { display: flex; flex-direction: column; gap: 2px; }
|
||
.rb-step-type {
|
||
font-family: var(--rb-body); font-size: 11px; font-weight: 700;
|
||
letter-spacing: .04em; text-transform: uppercase; color: var(--rb-white);
|
||
}
|
||
.rb-step-state { font-size: 11px; color: var(--rb-muted); text-transform: uppercase; letter-spacing: .04em; }
|
||
.rb-steps-compact .rb-step { grid-template-columns: 22px auto 1fr; padding: 4px 0; }
|
||
|
||
/* ============================================================
|
||
EXPEDITION — tracks, next leg, standings
|
||
============================================================ */
|
||
|
||
.rb-track { flex-direction: column; gap: 3px; padding: 9px 8px; }
|
||
.rb-track-row { display: flex; align-items: center; justify-content: center; gap: 10px; }
|
||
.rb-track-btn {
|
||
font-family: var(--rb-body); font-size: 16px; font-weight: 700; line-height: 1;
|
||
width: 22px; height: 22px; display: flex; align-items: center; justify-content: center;
|
||
border: 1px solid var(--rb-line); color: var(--rb-muted);
|
||
}
|
||
.rb-track-btn:hover { background: var(--rb-yellow); border-color: var(--rb-yellow); color: var(--rb-void); }
|
||
.rb-track-val { font-size: 30px; line-height: 1; }
|
||
.rb-track-max { font-size: 10px; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--rb-muted); }
|
||
.rb-track-pips { display: none; }
|
||
.rb-track-low .rb-track-val { color: var(--rb-white); }
|
||
.rb-track-low { border-color: var(--rb-yellow); }
|
||
.rb-track-crisis { border-color: var(--rb-danger); }
|
||
.rb-track-crisis .rb-track-val { color: var(--rb-danger); }
|
||
.rb-track-crisis .rb-pip.on { background: var(--rb-danger); }
|
||
|
||
.rb-progress { font-size: 11px; color: var(--rb-muted); text-transform: uppercase;
|
||
letter-spacing: .04em; font-weight: 700; display: flex; gap: 5px; align-items: center; }
|
||
.rb-progress strong { color: var(--rb-white); font-size: 13px; }
|
||
|
||
.rb-nextleg {
|
||
border: 1px solid var(--rb-yellow-dim);
|
||
background: var(--rb-void);
|
||
padding: 12px; margin-bottom: 16px;
|
||
}
|
||
.rb-nextleg-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 8px; }
|
||
.rb-nextleg-n {
|
||
font-family: var(--rb-body); font-size: 10px; font-weight: 700;
|
||
letter-spacing: .06em; text-transform: uppercase;
|
||
color: var(--rb-void); background: var(--rb-yellow); padding: 2px 7px;
|
||
}
|
||
.rb-nextleg-terrain { font-size: 14px; font-weight: 700; color: var(--rb-white); }
|
||
.rb-unexplored {
|
||
margin-left: auto; font-family: var(--rb-body); font-size: 10px; font-weight: 700;
|
||
letter-spacing: .04em; text-transform: uppercase; color: var(--rb-white);
|
||
border: 1px solid var(--rb-line); padding: 1px 6px;
|
||
}
|
||
.rb-nextleg-stats {
|
||
display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
|
||
gap: 6px 14px; margin-bottom: 10px;
|
||
}
|
||
.rb-rolltarget {
|
||
display: flex; align-items: baseline; gap: 9px;
|
||
border-top: 1px solid var(--rb-line); border-bottom: 1px solid var(--rb-line);
|
||
padding: 7px 0; margin-bottom: 10px;
|
||
}
|
||
.rb-rolltarget-label {
|
||
font-family: var(--rb-body); font-size: 10px; font-weight: 700;
|
||
letter-spacing: .04em; text-transform: uppercase; color: var(--rb-muted);
|
||
}
|
||
.rb-rolltarget-val {
|
||
font-family: var(--rb-body); font-size: 26px; font-weight: 700;
|
||
font-variant-numeric: tabular-nums; color: var(--rb-yellow); line-height: 1;
|
||
}
|
||
.rb-rolltarget-note { font-size: 11px; color: var(--rb-muted); margin-left: auto; }
|
||
.rb-bigbutton[disabled] {
|
||
border-color: var(--rb-line); color: var(--rb-muted); cursor: not-allowed; opacity: .55;
|
||
}
|
||
.rb-bigbutton[disabled]:hover { background: transparent; color: var(--rb-muted); }
|
||
.rb-nextleg-stats > span { display: flex; align-items: baseline; gap: 5px; }
|
||
.rb-nextleg-encounter {
|
||
font-size: 12px; color: var(--rb-danger); margin: 0 0 10px;
|
||
border-left: 3px solid var(--rb-danger); padding-left: 9px;
|
||
}
|
||
.rb-nextleg .rb-bigbutton { margin-bottom: 0; }
|
||
|
||
.rb-itinerary td { font-size: 12px; }
|
||
.rb-leg-n { font-weight: 700; color: var(--rb-muted); width: 24px; }
|
||
.rb-leg-event { font-size: 11px; color: var(--rb-danger); }
|
||
.rb-yes { color: var(--rb-good); }
|
||
.rb-no { color: var(--rb-muted); }
|
||
|
||
.rb-project, .rb-group {
|
||
border: 1px solid var(--rb-hairline); padding: 10px 12px; margin-bottom: 12px;
|
||
}
|
||
.rb-project-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 5px; }
|
||
.rb-project-status {
|
||
margin-left: auto; font-size: 10px; font-weight: 700; letter-spacing: .04em;
|
||
text-transform: uppercase; color: var(--rb-muted);
|
||
}
|
||
.rb-project-q { font-size: 12px; font-style: italic; color: var(--rb-muted); margin: 0 0 8px; }
|
||
.rb-disc-state {
|
||
width: 10px; height: 10px; border: 1px solid var(--rb-muted); display: inline-block; flex: 0 0 10px;
|
||
}
|
||
.rb-disc-state.on { background: var(--rb-good); border-color: var(--rb-good); }
|
||
|
||
.rb-standings li { flex-wrap: wrap; }
|
||
.rb-standing-scale { display: flex; gap: 2px; margin-left: auto; }
|
||
.rb-scale-cell {
|
||
font-family: var(--rb-body); font-size: 10px; font-weight: 700;
|
||
width: 24px; text-align: center; line-height: 18px;
|
||
border: 1px solid var(--rb-hairline); color: var(--rb-muted);
|
||
}
|
||
.rb-scale-cell.on { color: var(--rb-void); }
|
||
.rb-scale-good.on { background: var(--rb-yellow); border-color: var(--rb-yellow); }
|
||
.rb-scale-bad.on { background: var(--rb-danger); border-color: var(--rb-danger); }
|
||
|
||
/* standing as a signed value plus its word, not a seven-box rating widget */
|
||
.rb-standing-value {
|
||
font-family: var(--rb-body); font-size: 15px; font-weight: 700;
|
||
font-variant-numeric: tabular-nums; color: var(--rb-white);
|
||
min-width: 30px; text-align: right;
|
||
}
|
||
.rb-standing-good { color: var(--rb-white); }
|
||
.rb-standing-bad { color: var(--rb-danger); }
|
||
.rb-standing-scale { display: none; }
|
||
.rb-stat-small { font-size: 12px; font-weight: 400; color: var(--rb-muted); }
|
||
|
||
/* ---- hit locations ---- */
|
||
.rb-species-select { width: 130px; font-size: 12px; margin-left: 4px; }
|
||
.rb-loctable td { font-size: 12px; }
|
||
.rb-mono-cell { font-family: var(--rb-mono); font-size: 11px; color: var(--rb-muted); text-align: right; }
|
||
/* was display:flex on a <td>, which takes the cell out of table layout entirely */
|
||
.rb-loc-cell { white-space: nowrap; }
|
||
.rb-loc-flag {
|
||
font-family: var(--rb-body); font-size: 9px; font-weight: 700; letter-spacing: .04em;
|
||
text-transform: uppercase; color: var(--rb-void); background: var(--rb-yellow); padding: 0 5px;
|
||
}
|
||
.rb-loc-flag-x { background: var(--rb-danger); }
|
||
.rb-loc-row-disabled td { color: var(--rb-yellow); }
|
||
.rb-loc-row-destroyed td { color: var(--rb-danger); }
|
||
.rb-location .rb-loc-name { font-size: 17px; font-weight: 700; color: var(--rb-white); }
|
||
.rb-location .rb-loc-dmg { font-size: 26px; font-weight: 700; font-variant-numeric: tabular-nums; color: var(--rb-yellow); }
|
||
.rb-location .rb-loc-of { font-family: var(--rb-mono); font-size: 12px; color: var(--rb-muted); }
|
||
.rb-loc-effect { font-size: 12px; margin: 8px 0 0; border-left: 3px solid var(--rb-yellow); padding-left: 9px; }
|
||
.rb-loc-disabled .rb-loc-effect { border-left-color: var(--rb-yellow); }
|
||
.rb-loc-destroyed .rb-loc-effect { border-left-color: var(--rb-danger); color: var(--rb-danger); }
|
||
.rb-sr-action {
|
||
display: block; font-family: var(--rb-body); font-size: 9px; font-weight: 700;
|
||
letter-spacing: .04em; text-transform: uppercase; color: var(--rb-yellow);
|
||
}
|
||
.rb-sr-action.rb-sr-default { color: var(--rb-muted); font-weight: 400; font-style: italic; }
|
||
|
||
|
||
/* --- House dice ---------------------------------------------------------
|
||
Two chips, tens and units, read the way the table reads a percentile roll.
|
||
Squared, flat, no gradient — the same discipline as every other panel. */
|
||
.rb-chat-result { display: flex; align-items: center; gap: 12px; }
|
||
.rb-dice { display: flex; gap: 5px; }
|
||
.rb-die {
|
||
position: relative;
|
||
min-width: 34px; height: 34px;
|
||
display: flex; align-items: center; justify-content: center;
|
||
background: var(--rb-deep);
|
||
border: 1px solid var(--rb-line);
|
||
box-shadow: inset 0 0 0 1px var(--rb-void);
|
||
font-family: var(--rb-display); font-size: 14px; line-height: 1;
|
||
color: var(--rb-yellow);
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
/* The tens die carries the arc: one yellow hairline, the shape everyone knows. */
|
||
.rb-die-tens::after {
|
||
content: ""; position: absolute; left: 3px; right: 3px; bottom: 3px; height: 7px;
|
||
border-top: 1px solid var(--rb-hairline);
|
||
border-radius: 60% 60% 0 0 / 100% 100% 0 0;
|
||
}
|
||
.rb-die-units { background: var(--rb-blue); }
|
||
.rb-chat-outcome { display: flex; flex-direction: column; gap: 1px; }
|
||
.rb-axis { font-size: 10px; color: var(--rb-muted); margin: 3px 0 0; }
|
||
|
||
/* --- Coherence -----------------------------------------------------------
|
||
The one place red is allowed: it marks a character coming apart. */
|
||
.rb-coherence .rb-coh-reason { font-size: 11px; color: var(--rb-muted); }
|
||
.rb-coh-track { display: flex; gap: 3px; margin: 7px 0; }
|
||
.rb-coh-track .rb-pip {
|
||
width: 12px; height: 12px; background: transparent; border: 1px solid var(--rb-line);
|
||
}
|
||
.rb-coh-track .rb-pip.on { background: var(--rb-yellow); border-color: var(--rb-yellow); }
|
||
.rb-coh-crossed {
|
||
margin: 6px 0 0; padding: 5px 7px; border-left: 2px solid var(--rb-yellow);
|
||
font-size: 11px; color: var(--rb-white);
|
||
}
|
||
.rb-coh-unmoored .rb-coh-track .rb-pip.on,
|
||
.rb-coh-displaced .rb-coh-track .rb-pip.on { background: #e2564d; border-color: #e2564d; }
|
||
.rb-cohgroup .rb-cohband {
|
||
display: block; font-family: var(--rb-body); font-size: 8px; font-weight: 700;
|
||
letter-spacing: .08em; text-transform: uppercase; color: var(--rb-muted);
|
||
}
|
||
.rb-cohbtn { color: var(--rb-yellow); padding: 0 5px; cursor: pointer; }
|
||
.rb-cohgroup.rb-coh-unmoored .rb-cohband,
|
||
.rb-cohgroup.rb-coh-displaced .rb-cohband { color: #e2564d; }
|
||
.rb-rank {
|
||
display: block; width: 100%; background: transparent; border: 0;
|
||
border-bottom: 1px solid var(--rb-hairline); padding: 1px 0 2px;
|
||
font-family: var(--rb-body); font-size: 10px; font-weight: 700;
|
||
letter-spacing: .12em; text-transform: uppercase; color: var(--rb-muted);
|
||
}
|
||
.rb-rank:focus { outline: none; border-bottom-color: var(--rb-yellow); color: var(--rb-white); }
|
||
.rb-caseline { display: flex; gap: 8px; margin: 0 0 8px; }
|
||
.rb-across, .rb-debrief, .rb-closecase {
|
||
font-family: var(--rb-body); font-size: 10px; font-weight: 700;
|
||
letter-spacing: .1em; text-transform: uppercase; padding: 4px 10px;
|
||
border: 1px solid var(--rb-line); color: var(--rb-muted); cursor: pointer;
|
||
}
|
||
.rb-across.on { background: var(--rb-yellow); border-color: var(--rb-yellow); color: var(--rb-void); }
|
||
.rb-closecase { margin-left: auto; border-color: var(--rb-yellow); color: var(--rb-yellow); }
|
||
.rb-disabled { opacity: .4; pointer-events: none; }
|
||
|
||
/* --- Talents ------------------------------------------------------------- */
|
||
.rb-talents { list-style: none; margin: 0 0 14px; padding: 0; }
|
||
.rb-talent {
|
||
display: grid; grid-template-columns: 40px 1fr auto 18px;
|
||
gap: 10px; align-items: start;
|
||
padding: 8px 6px; border-bottom: 1px solid var(--rb-hairline);
|
||
}
|
||
.rb-talent-icon { width: 38px; height: 38px; border: 1px solid var(--rb-line); }
|
||
.rb-talent-name {
|
||
display: block; font-family: var(--rb-body); font-size: 12px; font-weight: 700;
|
||
letter-spacing: .04em; text-transform: uppercase; color: var(--rb-yellow);
|
||
}
|
||
.rb-talent-summary { font-size: 12px; color: var(--rb-white); margin: 2px 0 3px; }
|
||
.rb-talent-rule { font-size: 11px; color: var(--rb-muted); line-height: 1.35; }
|
||
.rb-talent-cost { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; }
|
||
.rb-talent-coh {
|
||
font-family: var(--rb-body); font-size: 11px; font-weight: 700;
|
||
color: #e2564d; border: 1px solid #e2564d; padding: 1px 5px;
|
||
}
|
||
.rb-talent-uses, .rb-talent-bonus {
|
||
font-family: var(--rb-body); font-size: 10px; font-weight: 700;
|
||
color: var(--rb-muted); font-variant-numeric: tabular-nums;
|
||
}
|
||
|
||
/* Item icons in lists: small, square, never competing with the value beside them */
|
||
.rb-li-icon {
|
||
width: 22px; height: 22px; vertical-align: middle;
|
||
margin-right: 7px; border: 1px solid var(--rb-hairline); flex: 0 0 auto;
|
||
}
|
||
.rb-td-icon { white-space: nowrap; }
|
||
.rb-skill .rb-li-icon { width: 18px; height: 18px; margin: 0; }
|
||
|
||
/* --- Contact and device controls ---------------------------------------- */
|
||
.rb-contact-bar, .rb-devicebar {
|
||
display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
|
||
margin: 7px 0 2px; padding: 6px 0 0; border-top: 1px solid var(--rb-hairline);
|
||
}
|
||
.rb-cbtn {
|
||
font-family: var(--rb-body); font-size: 10px; font-weight: 700;
|
||
letter-spacing: .08em; text-transform: uppercase;
|
||
padding: 3px 9px; border: 1px solid var(--rb-line);
|
||
color: var(--rb-yellow); cursor: pointer;
|
||
}
|
||
.rb-cbtn:hover { background: var(--rb-yellow); color: var(--rb-void); border-color: var(--rb-yellow); }
|
||
.rb-cbtn-alt { color: var(--rb-muted); }
|
||
.rb-cstate { font-size: 11px; color: var(--rb-muted); margin-left: auto; }
|
||
.rb-devfn { display: flex; align-items: center; gap: 6px; }
|
||
.rb-devfn-why { font-size: 10px; color: var(--rb-muted); }
|
||
.rb-devfn-blocked .rb-devfn-why { color: #e2564d; }
|
||
.rb-talent-passive {
|
||
font-family: var(--rb-body); font-size: 9px; font-weight: 700;
|
||
letter-spacing: .08em; text-transform: uppercase; color: var(--rb-muted);
|
||
}
|
||
|
||
/* --- Generator buttons --------------------------------------------------- */
|
||
.rb-genbar { display: flex; gap: 6px; padding: 6px 4px; }
|
||
.rb-genbtn {
|
||
flex: 1; font-family: var(--rb-body); font-size: 10px; font-weight: 700;
|
||
letter-spacing: .08em; text-transform: uppercase;
|
||
padding: 5px 8px; background: var(--rb-deep);
|
||
border: 1px solid var(--rb-line); color: var(--rb-yellow); cursor: pointer;
|
||
}
|
||
.rb-genbtn:hover { background: var(--rb-yellow); color: var(--rb-void); border-color: var(--rb-yellow); }
|
||
.rb-gen .form-group { margin-bottom: 6px; }
|
||
.rb-skillbar { display: flex; align-items: center; gap: 10px; margin: 0 0 8px; }
|
||
.rb-skillbar .rb-dim { margin-right: auto; font-size: 11px; }
|
||
.rb-skill-empty { font-size: 11px; color: var(--rb-muted); padding: 3px 0 3px 20px; font-style: italic; }
|
||
|
||
/* --- Reaction rail -------------------------------------------------------
|
||
The paper sheet's seven boxes, on screen. The base is the only number the
|
||
player ever calculates; the rail is filled in once and clipped thereafter. */
|
||
.rb-railbox { border: 1px solid var(--rb-hairline); padding: 10px; margin: 0 0 14px; }
|
||
.rb-rail-head { display: flex; align-items: baseline; gap: 10px; margin-bottom: 8px; }
|
||
.rb-rail-base {
|
||
font-family: var(--rb-display); font-size: 26px; color: var(--rb-yellow);
|
||
font-variant-numeric: tabular-nums; line-height: 1;
|
||
}
|
||
.rb-rail-cap {
|
||
font-family: var(--rb-body); font-size: 10px; font-weight: 700;
|
||
letter-spacing: .1em; text-transform: uppercase; color: var(--rb-white);
|
||
}
|
||
.rb-rail-head .rb-dim { margin-left: auto; font-size: 11px; }
|
||
.rb-rail { border-collapse: collapse; width: 100%; }
|
||
.rb-rail th, .rb-rail td {
|
||
border: 1px solid var(--rb-hairline); padding: 4px 0; text-align: center;
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
.rb-rail th { font-family: var(--rb-body); font-size: 10px; color: var(--rb-muted); font-weight: 700; }
|
||
.rb-rail td { font-family: var(--rb-body); font-size: 15px; color: var(--rb-white); }
|
||
.rb-rail th.on, .rb-rail td.on { background: var(--rb-yellow); color: var(--rb-void); border-color: var(--rb-yellow); }
|
||
|
||
/* --- Reaction chat card --- */
|
||
.rb-reactlist { list-style: none; margin: 6px 0 0; padding: 0; }
|
||
.rb-reactrow {
|
||
display: grid; grid-template-columns: 34px 1fr auto auto; gap: 8px;
|
||
align-items: baseline; padding: 3px 0; border-bottom: 1px solid var(--rb-hairline);
|
||
}
|
||
.rb-react-total {
|
||
font-family: var(--rb-body); font-size: 16px; font-weight: 700;
|
||
color: var(--rb-yellow); text-align: right; font-variant-numeric: tabular-nums;
|
||
}
|
||
.rb-react-name { font-size: 12px; color: var(--rb-white); }
|
||
.rb-react-calc { font-family: var(--rb-mono); font-size: 10px; color: var(--rb-muted); }
|
||
.rb-react-flag, .rb-misfiled .rb-sr-action {
|
||
font-family: var(--rb-body); font-size: 9px; font-weight: 700;
|
||
letter-spacing: .08em; color: #e2564d;
|
||
}
|
||
.rb-checkrow { display: flex; gap: 16px; }
|
||
.rb-reactdlg .rb-rail { margin-bottom: 8px; }
|
||
|
||
/* Damage offered by a successful attack card */
|
||
.rb-chat-damage { display: flex; align-items: center; gap: 8px; margin: 6px 0 2px; flex-wrap: wrap; }
|
||
.rb-dmg-btn {
|
||
flex: 0 1 auto; padding: 3px 10px; cursor: pointer;
|
||
background: var(--rb-panel); color: var(--rb-yellow);
|
||
border: 1px solid var(--rb-yellow); border-radius: 3px;
|
||
font-family: inherit; font-size: 0.85rem; letter-spacing: 0.04em; text-transform: uppercase;
|
||
}
|
||
.rb-dmg-btn:hover:not(:disabled) { background: var(--rb-yellow); color: var(--rb-panel); }
|
||
.rb-dmg-btn:disabled { opacity: 0.45; cursor: default; }
|
||
.rb-dmg-btn i { margin-right: 4px; }
|
||
.rb-dmg-note { font-size: 0.75rem; font-style: italic; color: var(--rb-muted, #9fb0d9); }
|
||
|
||
/* Carried but not worn — the ARMOUR box says why it reads zero */
|
||
.rb-armour.rb-unworn { position: relative; border-color: var(--rb-danger, #d9534f); }
|
||
.rb-armour.rb-unworn .rb-big { color: var(--rb-danger, #d9534f); }
|
||
.rb-unworn-flag {
|
||
display: block; font-size: 0.6rem; letter-spacing: 0.08em; text-transform: uppercase;
|
||
color: var(--rb-danger, #d9534f); margin-top: -2px;
|
||
}
|
||
|
||
/* Reaction — the working, so the printed number is not a magic figure */
|
||
.rb-react-work { margin: 4px 0 2px; font-size: 0.78rem; }
|
||
.rb-react-work summary { cursor: pointer; color: var(--rb-yellow); letter-spacing: 0.03em; }
|
||
.rb-worktable { width: 100%; border-collapse: collapse; margin-top: 4px; }
|
||
.rb-worktable th { text-align: left; font-weight: 600; padding: 1px 6px 1px 0; white-space: nowrap; }
|
||
.rb-worktable td { padding: 1px 0; color: var(--rb-muted, #9fb0d9); }
|
||
.rb-worknum { text-align: right; font-weight: 700; color: var(--rb-white); width: 3em; }
|
||
.rb-worknote td { font-style: italic; font-size: 0.72rem; padding-bottom: 3px; }
|
||
.rb-workload .rb-worknum { color: var(--rb-danger, #d9534f); }
|
||
.rb-worktotal th, .rb-worktotal .rb-worknum { border-top: 1px solid var(--rb-line, #3b4a80); padding-top: 3px; }
|
||
.rb-worktotal .rb-worknum { color: var(--rb-yellow); font-size: 1rem; }
|
||
|
||
/* ============================================================
|
||
The figure, and the hit-location table beside it
|
||
============================================================ */
|
||
.rb-bodyblock {
|
||
display: grid; grid-template-columns: minmax(130px, 170px) minmax(0, 1fr);
|
||
gap: 18px; align-items: start; margin-bottom: 12px;
|
||
}
|
||
/* On a wide sheet the table used to stretch the full window, throwing the numbers
|
||
a foot away from the names they belong to. */
|
||
.rb-bodyside { max-width: 560px; }
|
||
.rb-figure { display: flex; flex-direction: column; align-items: center; gap: 4px; }
|
||
.rb-body-svg { width: 100%; max-width: 180px; height: auto; display: block; }
|
||
.rb-figure-species {
|
||
font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase;
|
||
color: var(--rb-muted, #9fb0d9);
|
||
}
|
||
.rb-figure-roll { font-size: 0.72rem; }
|
||
|
||
/* Damage state. Read at a glance: pale = whole, red = gone. */
|
||
.rb-part {
|
||
stroke: var(--rb-line, #3b4a80); stroke-width: 1.5;
|
||
fill: var(--rb-blue); transition: fill 120ms ease;
|
||
}
|
||
.rb-part-whole { fill: var(--rb-blue); }
|
||
.rb-part-grazed { fill: #6d7a3f; }
|
||
.rb-part-hurt { fill: #a8722c; }
|
||
.rb-part-disabled { fill: #b2402f; stroke: #e08b7c; }
|
||
.rb-part-destroyed { fill: #5d1b16; stroke: #e08b7c; stroke-dasharray: 3 2; }
|
||
.rb-part:hover { stroke: var(--rb-yellow); stroke-width: 2.2; }
|
||
|
||
/* The table was ragged because every column sized itself to its content.
|
||
Fixed layout plus tabular numerals lines the digits up. */
|
||
/* Auto layout, not fixed. Fixed sized every column from the HEADER row, where the
|
||
font is smaller, so 3.6em came out at ~39px and "RANGED" overflowed into its
|
||
neighbour — which is why the header read MELEERANGETAKENARMO. Auto layout sizes
|
||
each column to its widest cell instead, and nowrap stops the ranges breaking
|
||
across two lines. The name column takes 99% so it absorbs all the slack and the
|
||
numbers stay gathered on the right. */
|
||
.rb-loctable { table-layout: auto; width: auto; border-collapse: collapse; }
|
||
.rb-loctable th, .rb-loctable td {
|
||
padding: 3px 10px; vertical-align: middle; white-space: nowrap;
|
||
}
|
||
.rb-loctable th:first-child, .rb-loctable td:first-child { padding-left: 2px; }
|
||
.rb-loctable th:last-child, .rb-loctable td:last-child { padding-right: 2px; }
|
||
/* Content-sized, not stretched. Giving the name column the slack pushed the
|
||
numbers to the far edge of the panel, a hand's width from the row they describe.
|
||
The table is now only as wide as it needs to be and the gutter is a fixed
|
||
readable gap. */
|
||
.rb-col-loc { width: auto; text-align: left; padding-right: 22px; min-width: 6.5em; }
|
||
.rb-col-num { width: auto; text-align: right; font-variant-numeric: tabular-nums; }
|
||
.rb-loctable thead th {
|
||
font-size: 0.62rem; letter-spacing: 0.06em; text-transform: uppercase; font-weight: 600;
|
||
color: var(--rb-muted, #9fb0d9); border-bottom: 1px solid var(--rb-line, #3b4a80);
|
||
padding-bottom: 4px;
|
||
}
|
||
.rb-loctable tbody td { font-size: 0.8rem; border-bottom: 1px solid var(--rb-hairline, #2a3763); }
|
||
.rb-loctable tbody tr:last-child td { border-bottom: none; }
|
||
.rb-loctable-compact th, .rb-loctable-compact td { padding: 2px 8px; }
|
||
.rb-loctable-compact tbody td { font-size: 0.76rem; }
|
||
.rb-locrow-disabled td { color: #e8a99e; }
|
||
.rb-locrow-destroyed td { color: #e08b7c; text-decoration: line-through; }
|
||
.rb-locrow.rb-hi td { background: rgba(255, 215, 94, 0.12); }
|
||
|
||
.rb-sub-head {
|
||
margin: 8px 0 3px; font-size: 0.72rem; letter-spacing: 0.08em;
|
||
text-transform: uppercase; color: var(--rb-yellow);
|
||
border-bottom: 1px solid var(--rb-line, #3b4a80); padding-bottom: 2px;
|
||
}
|
||
.rb-wounds-compact li { font-size: 0.78rem; padding: 2px 0; }
|
||
|
||
/* Wounded banner on the skills tab — you cannot miss what is modifying every roll */
|
||
.rb-woundbar {
|
||
display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
|
||
margin: 0 0 8px; padding: 5px 9px; border-radius: 3px;
|
||
background: rgba(178, 64, 47, 0.16); border: 1px solid var(--rb-danger, #b2402f);
|
||
}
|
||
.rb-woundbar-title {
|
||
font-size: 0.72rem; letter-spacing: 0.08em; text-transform: uppercase;
|
||
color: var(--rb-danger, #d9534f); font-weight: 700;
|
||
}
|
||
.rb-woundchip {
|
||
font-size: 0.72rem; padding: 1px 7px; border-radius: 9px;
|
||
background: rgba(0, 0, 0, 0.28); color: var(--rb-white);
|
||
}
|
||
.rb-woundbar-pen { font-size: 0.72rem; color: var(--rb-muted, #9fb0d9); margin-left: auto; }
|
||
|
||
@media (max-width: 620px) { .rb-bodyblock { grid-template-columns: 1fr; } }
|
||
|
||
/* The figure's roll button was carrying a full sentence and wrapped to three
|
||
lines. Short label, sentence moved to the tooltip. */
|
||
.rb-figure-roll {
|
||
display: inline-block; white-space: nowrap; text-align: center;
|
||
font-size: 0.7rem; letter-spacing: 0.04em; padding: 3px 10px; margin-top: 2px;
|
||
}
|
||
/* "No active wounds." was centred in a wide empty box, floating in the middle of
|
||
nothing. It belongs on the left, under its heading, like every other row. */
|
||
.rb-bodyside .rb-empty {
|
||
text-align: left; margin: 2px 0 0; font-size: 0.76rem; font-style: italic;
|
||
color: var(--rb-muted, #9fb0d9);
|
||
}
|
||
.rb-bodyside .rb-sub-head { margin-top: 12px; }
|
||
|
||
/* ============================================================
|
||
Dialogs — the callout boxes, dressed as the sheet
|
||
Foundry's default is parchment and a serif face, which read as
|
||
a different application sitting on top of the character sheet.
|
||
============================================================ */
|
||
.ringbrp-window.window-app,
|
||
.ringbrp-window.application {
|
||
background: var(--rb-deep);
|
||
color: var(--rb-white);
|
||
font-family: var(--rb-body);
|
||
border: 1px solid var(--rb-line);
|
||
border-radius: 3px;
|
||
box-shadow: 0 8px 28px rgba(0, 0, 0, 0.55);
|
||
}
|
||
.ringbrp-window .window-header {
|
||
background: var(--rb-void);
|
||
border-bottom: 1px solid var(--rb-line);
|
||
color: var(--rb-yellow);
|
||
font-family: var(--rb-display);
|
||
font-size: 11px;
|
||
letter-spacing: 0.08em;
|
||
text-transform: uppercase;
|
||
padding: 7px 10px;
|
||
}
|
||
.ringbrp-window .window-header .window-title { font-family: var(--rb-display); font-size: 11px; }
|
||
.ringbrp-window .window-header a,
|
||
.ringbrp-window .window-header .header-button { color: var(--rb-muted); text-transform: none; }
|
||
.ringbrp-window .window-header a:hover { color: var(--rb-yellow); }
|
||
.ringbrp-window .window-content {
|
||
background: var(--rb-deep);
|
||
color: var(--rb-white);
|
||
font-family: var(--rb-body);
|
||
font-size: 13px;
|
||
padding: 12px 14px;
|
||
}
|
||
|
||
/* form rows: label left, control right, note beneath in muted small caps */
|
||
.ringbrp-window .form-group { display: block; margin-bottom: 12px; }
|
||
.ringbrp-window .form-group > label {
|
||
display: block; margin-bottom: 4px;
|
||
font-family: var(--rb-body); font-weight: 700;
|
||
font-size: 10px; letter-spacing: 0.09em; text-transform: uppercase;
|
||
color: var(--rb-muted);
|
||
}
|
||
.ringbrp-window .form-group > label.rb-check {
|
||
display: flex; align-items: center; gap: 8px;
|
||
font-size: 13px; letter-spacing: 0; text-transform: none;
|
||
font-weight: 400; color: var(--rb-white); margin-bottom: 0;
|
||
}
|
||
.ringbrp-window input[type="text"],
|
||
.ringbrp-window input[type="number"],
|
||
.ringbrp-window select,
|
||
.ringbrp-window textarea {
|
||
width: 100%; box-sizing: border-box;
|
||
background: var(--rb-panel);
|
||
color: var(--rb-white);
|
||
border: 1px solid var(--rb-line);
|
||
border-radius: 2px;
|
||
padding: 5px 8px;
|
||
font-family: var(--rb-body); font-size: 13px;
|
||
font-variant-numeric: tabular-nums;
|
||
}
|
||
.ringbrp-window select option { background: var(--rb-panel); color: var(--rb-white); }
|
||
.ringbrp-window input:focus, .ringbrp-window select:focus {
|
||
outline: none; border-color: var(--rb-yellow);
|
||
box-shadow: 0 0 0 2px var(--rb-yellow-dim);
|
||
}
|
||
.ringbrp-window input[type="checkbox"] {
|
||
width: 15px; height: 15px; accent-color: var(--rb-yellow); margin: 0; flex: 0 0 auto;
|
||
}
|
||
.ringbrp-window .notes, .ringbrp-window .hint, .ringbrp-window p.notes {
|
||
margin: 4px 0 0; font-size: 11px; line-height: 1.35;
|
||
color: var(--rb-muted); font-style: normal;
|
||
}
|
||
|
||
/* buttons: yellow means the thing that commits */
|
||
.ringbrp-window .dialog-buttons { gap: 8px; margin-top: 4px; }
|
||
.ringbrp-window .dialog-button, .ringbrp-window button {
|
||
background: var(--rb-panel);
|
||
color: var(--rb-white);
|
||
border: 1px solid var(--rb-line);
|
||
border-radius: 2px;
|
||
font-family: var(--rb-body); font-weight: 700;
|
||
font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
|
||
padding: 7px 12px; line-height: 1;
|
||
}
|
||
.ringbrp-window .dialog-button:hover, .ringbrp-window button:hover {
|
||
background: var(--rb-blue); border-color: var(--rb-yellow); color: var(--rb-yellow);
|
||
}
|
||
.ringbrp-window .dialog-button.default,
|
||
.ringbrp-window .dialog-buttons button:first-child {
|
||
background: var(--rb-yellow); color: var(--rb-void); border-color: var(--rb-yellow);
|
||
}
|
||
.ringbrp-window .dialog-button.default:hover,
|
||
.ringbrp-window .dialog-buttons button:first-child:hover {
|
||
background: var(--rb-white); color: var(--rb-void);
|
||
}
|
||
.ringbrp-window a { color: var(--rb-yellow); }
|
||
.ringbrp-window hr { border: none; border-top: 1px solid var(--rb-hairline); margin: 10px 0; }
|
||
|
||
/* Defending — the counter is the point: it shows what the next one costs */
|
||
.rb-defbar { display: flex; align-items: center; gap: 8px; margin: 6px 0 10px; flex-wrap: wrap; }
|
||
.rb-defbar-label {
|
||
font-size: 0.68rem; letter-spacing: 0.09em; text-transform: uppercase;
|
||
color: var(--rb-muted); font-weight: 700;
|
||
}
|
||
.rb-defbar-count { font-size: 0.74rem; color: var(--rb-muted); margin-left: auto; }
|
||
|
||
/* Weight sits with the rest of an item's numbers, tabular so a kit list scans */
|
||
.rb-mass { font-variant-numeric: tabular-nums; }
|
||
.rb-table .rb-col-num { text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
|
||
|
||
/* The Quiet Arts — read as documents, not as a spell list */
|
||
.rb-powers > li { padding: 8px 0 10px; border-bottom: 1px solid var(--rb-hairline); }
|
||
.rb-powers > li:last-child { border-bottom: none; }
|
||
.rb-power-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
|
||
.rb-power-name { font-family: var(--rb-display); font-size: 12px; letter-spacing: 0.04em; }
|
||
.rb-power-val { font-weight: 700; font-variant-numeric: tabular-nums; color: var(--rb-yellow); }
|
||
.rb-power-cost {
|
||
font-size: 0.72rem; padding: 1px 7px; border-radius: 9px;
|
||
background: rgba(0,0,0,0.28); color: var(--rb-danger);
|
||
}
|
||
.rb-power-push { margin-left: auto; }
|
||
.rb-power-summary { margin: 5px 0 2px; font-style: italic; color: var(--rb-white); font-size: 12px; }
|
||
.rb-power-rule { margin: 0; color: var(--rb-muted); font-size: 12px; line-height: 1.4; }
|
||
.rb-power-origin { margin: 4px 0 0; font-size: 11px; color: var(--rb-yellow-dim); }
|
||
.rb-power-granted, .rb-misfiled .rb-power-granted { border-left: 3px solid var(--rb-yellow); padding-left: 8px; }
|
||
|
||
/* The crossing panel — the one control the whole premise runs through */
|
||
.rb-crossbox {
|
||
margin: 8px 0 12px; padding: 8px 10px; border-radius: 3px;
|
||
border: 1px solid var(--rb-line); background: var(--rb-panel);
|
||
}
|
||
.rb-crossbox-across { border-color: var(--rb-yellow); }
|
||
.rb-crossbox-head { display: flex; align-items: center; gap: 10px; }
|
||
.rb-crossbox-title {
|
||
font-family: var(--rb-display); font-size: 11px; letter-spacing: 0.08em;
|
||
text-transform: uppercase; color: var(--rb-yellow);
|
||
}
|
||
.rb-crossbox .rb-cross-all { margin-left: auto; }
|
||
.rb-crossbox .rb-hint { margin: 6px 0 8px; }
|
||
.rb-crosstable { width: 100%; }
|
||
.rb-crosstable .rb-actions { text-align: right; white-space: nowrap; }
|
||
.rb-crosstable .rb-actions .rb-cbtn { margin-left: 4px; }
|
||
.rb-artmark { color: var(--rb-yellow); font-size: 0.8em; }
|
||
|
||
/* --- Marksmanship: say what the choice buys ------------------------------ */
|
||
/* Both styles are shown, not just the chosen one — the point of the block is to
|
||
make the choice comparable at the moment it is made. */
|
||
.rb-style-compare {
|
||
list-style: none; margin: 4px 0 0; padding: 0;
|
||
display: grid; gap: 2px;
|
||
}
|
||
.rb-style-compare li {
|
||
font-family: var(--rb-body); font-size: 9px; line-height: 1.4;
|
||
color: var(--rb-muted); padding: 2px 5px;
|
||
border-left: 2px solid var(--rb-hairline);
|
||
}
|
||
.rb-style-compare li.on { color: var(--rb-white); border-left-color: var(--rb-yellow); }
|
||
.rb-style-compare b { color: var(--rb-line); font-weight: 700; letter-spacing: .06em; }
|
||
.rb-style-compare li.on b { color: var(--rb-yellow); }
|
||
|
||
/* --- Defence outcome ------------------------------------------------------ */
|
||
.rb-defence { border-left: 3px solid var(--rb-line); padding-left: 8px; }
|
||
.rb-defence.rb-aside { border-left-color: var(--rb-yellow); }
|
||
.rb-defence.rb-through { border-left-color: var(--rb-danger); }
|
||
|
||
/* --- Role card in the creation dialog ------------------------------------ */
|
||
.rb-rolecard {
|
||
margin: 6px 0 10px; padding: 8px 10px;
|
||
border-left: 2px solid var(--rb-yellow); background: var(--rb-deep);
|
||
}
|
||
.rb-rolecard-blurb {
|
||
margin: 0; font-family: var(--rb-body); font-size: 11px; line-height: 1.45;
|
||
color: var(--rb-white);
|
||
}
|
||
.rb-rolecard-facts {
|
||
display: grid; grid-template-columns: max-content 1fr; gap: 2px 10px;
|
||
margin: 7px 0 0; font-family: var(--rb-body); font-size: 10px; line-height: 1.4;
|
||
}
|
||
.rb-rolecard-facts dt {
|
||
color: var(--rb-muted); text-transform: uppercase; letter-spacing: .08em;
|
||
font-weight: 700; white-space: nowrap;
|
||
}
|
||
.rb-rolecard-facts dd { margin: 0; color: var(--rb-line); }
|
||
|
||
/* --- Transport on the gear tab -------------------------------------------- */
|
||
.rb-vehicles li { display: flex; gap: 10px; align-items: center; }
|
||
.rb-vehicles .rb-strong { flex: 1 1 auto; }
|
||
|
||
/* --- Borrowed Authority --------------------------------------------------- */
|
||
.rb-authorities li {
|
||
display: grid; gap: 3px; padding: 8px 6px;
|
||
border-bottom: 1px solid var(--rb-hairline);
|
||
border-left: 2px solid var(--rb-line);
|
||
}
|
||
.rb-authorities li.rb-auth-flagged { border-left-color: var(--rb-yellow); }
|
||
.rb-authorities li.rb-auth-dead { border-left-color: var(--rb-danger); opacity: .55; }
|
||
.rb-auth-head { display: flex; gap: 8px; align-items: center; }
|
||
.rb-auth-head .rb-strong { flex: 0 0 auto; }
|
||
.rb-auth-trust {
|
||
margin-left: auto; font-family: var(--rb-body); font-size: 10px; font-weight: 700;
|
||
letter-spacing: .06em; color: var(--rb-yellow);
|
||
}
|
||
.rb-auth-tag {
|
||
font-family: var(--rb-body); font-size: 9px; font-weight: 700; letter-spacing: .1em;
|
||
text-transform: uppercase; padding: 1px 6px; border: 1px solid var(--rb-yellow);
|
||
color: var(--rb-yellow);
|
||
}
|
||
.rb-auth-body { display: flex; gap: 12px; flex-wrap: wrap; font-size: 10px; }
|
||
.rb-auth-flags, .rb-auth-merge-tag {
|
||
font-family: var(--rb-body); font-size: 10px; color: var(--rb-yellow);
|
||
}
|
||
.rb-auth-acts { display: flex; gap: 6px; margin-top: 2px; }
|
||
.rb-auth-merge { margin: 6px 0 0; font-style: italic; color: var(--rb-yellow); }
|
||
.rb-auth.rb-auth-yes { border-left: 3px solid var(--rb-yellow); padding-left: 8px; }
|
||
.rb-auth.rb-auth-no { border-left: 3px solid var(--rb-line); padding-left: 8px; }
|
||
.rb-dossier { border-left: 3px solid var(--rb-line); padding-left: 8px; }
|
||
.rb-dossier-miss { opacity: .7; }
|
||
.rb-authuse .rb-check { display: block; font-size: 11px; margin: 2px 0; }
|
||
|
||
/* The case generator sits with the others but is the one that makes a whole case. */
|
||
.rb-genbtn-case { border-color: var(--rb-yellow); color: var(--rb-yellow); }
|
||
|
||
/* --- Dying and dead ------------------------------------------------------- */
|
||
.rb-dyingbar, .rb-deadbar {
|
||
display: flex; gap: 10px; align-items: baseline;
|
||
padding: 6px 10px; margin: 0 0 8px;
|
||
font-family: var(--rb-body); font-size: 11px;
|
||
border-left: 3px solid var(--rb-danger); background: var(--rb-deep);
|
||
}
|
||
.rb-dyingbar.rb-stable { border-left-color: var(--rb-yellow); }
|
||
.rb-deadbar { border-left-color: var(--rb-white); }
|
||
.rb-dyingbar-title {
|
||
font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
|
||
color: var(--rb-danger);
|
||
}
|
||
.rb-dyingbar.rb-stable .rb-dyingbar-title { color: var(--rb-yellow); }
|
||
.rb-deadbar .rb-dyingbar-title { color: var(--rb-white); }
|
||
.rb-dying { border-left: 3px solid var(--rb-danger); padding-left: 8px; }
|
||
.rb-stable { border-left: 3px solid var(--rb-yellow); padding-left: 8px; }
|
||
.rb-dead { border-left: 3px solid var(--rb-white); padding-left: 8px; }
|
||
|
||
/* ============================================================
|
||
THE PAUSE — containment hold
|
||
============================================================
|
||
Foundry's pause is <figure id="pause"> holding an <img> and a <figcaption>, and core
|
||
hides it with `#pause { display: none }` / shows it with `#pause.paused { display:
|
||
flex }`. An early version styled the bare #pause with display:flex and so overrode the
|
||
hide — the panel never went away when the game unpaused, and GAME PAUSED sat over the
|
||
table for the rest of the session. EVERY rule here that could affect visibility or
|
||
layout is therefore scoped to `.paused`, and `display` is not set anywhere. There is a
|
||
guard in check-behaviour.mjs that enforces exactly this.
|
||
|
||
Core also already centres it: a full-width band, column flex, centred both ways,
|
||
pointer-events none. That layout is correct and is left alone — only its size and its
|
||
looks change here. An earlier version repositioned it with left/bottom and pushed it
|
||
off centre for the trouble.
|
||
|
||
WHAT IT IS. The department is holding a moment still, and this is the instrument doing
|
||
the holding. It acquires, it locks, it reports the lock is good, it lets go.
|
||
|
||
There are only four paintable surfaces on this element — the figure's ::before and
|
||
::after, the <img>, and the <figcaption> — so each is given exactly one job and no
|
||
surface does two things:
|
||
|
||
::before the FIELD. Grid and containment ring. Static; it is the screen.
|
||
img the LOCK. Four corner brackets that close, snap, hold, release.
|
||
::after the SCAN. A line reading down the field, three passes per cycle.
|
||
figcaption the READOUT. Lifts when the lock takes, drops when it lets go.
|
||
|
||
The <img> keeps its box and loses its pixels: object-position walks the raster out of
|
||
frame, which leaves a paintable element without adding a wrapper to markup we do not
|
||
own.
|
||
|
||
THE CYCLE, 4.8s:
|
||
|
||
0–22% acquire brackets wide and dim, closing
|
||
22% LOCK they snap home; the readout comes up in the same frame
|
||
22–70% hold the moment is held
|
||
70–80% release brackets open and fade, readout drops
|
||
80–100% rest dark, before it goes again
|
||
|
||
The scan is cycle/3 rather than some free-running duration, so it divides the cycle
|
||
exactly and its third pass always lands on the lock instead of wandering across it.
|
||
Every animation here reads --rb-pause-cycle: change that one value and the whole
|
||
instrument re-times together, and nothing can drift out of phase with anything else.
|
||
============================================================ */
|
||
|
||
#pause.paused {
|
||
/* One cycle and one field size, read by every layer below. */
|
||
--rb-pause-cycle: 4.8s;
|
||
--rb-pause-field: 190px;
|
||
--rb-pause-gap: 26px;
|
||
--rb-pause-height: 300px;
|
||
/* The readout is pinned to exactly this so the column's height is known rather than
|
||
dependent on whether Michroma has loaded yet — see the figcaption rule. */
|
||
--rb-pause-readout: 25.2px; /* 21px x 1.2 line-height */
|
||
/* ::before and ::after are absolutely positioned and cannot see where flex put the
|
||
lock, so the offset is DERIVED from the column rather than measured and pasted in:
|
||
half the space left over once the field, the gap and the readout are accounted for.
|
||
Change the field size or the gap and this follows on its own. */
|
||
--rb-pause-top: calc((var(--rb-pause-height)
|
||
- var(--rb-pause-field)
|
||
- var(--rb-pause-gap)
|
||
- var(--rb-pause-readout)) / 2);
|
||
|
||
height: var(--rb-pause-height);
|
||
top: calc(50vh - (var(--rb-pause-height) / 2));
|
||
gap: var(--rb-pause-gap);
|
||
background: linear-gradient(to right,
|
||
transparent 0%,
|
||
color-mix(in srgb, var(--rb-void) 86%, transparent) 34%,
|
||
color-mix(in srgb, var(--rb-void) 86%, transparent) 66%,
|
||
transparent 100%);
|
||
}
|
||
|
||
/* THE FIELD — the screen the lock is drawn on. Ring inside a grid, both hairline, the
|
||
whole thing masked to fade out well before its own square edge so it reads as a
|
||
field of view rather than a box sitting on the canvas. */
|
||
#pause.paused::before {
|
||
content: "";
|
||
position: absolute;
|
||
top: var(--rb-pause-top);
|
||
left: 50%;
|
||
margin-left: calc(var(--rb-pause-field) / -2);
|
||
width: var(--rb-pause-field);
|
||
height: var(--rb-pause-field);
|
||
background:
|
||
radial-gradient(circle, transparent 0 71px, var(--rb-line) 71px 72px, transparent 72px),
|
||
repeating-linear-gradient(to right, var(--rb-line) 0 1px, transparent 1px 19px),
|
||
repeating-linear-gradient(to bottom, var(--rb-line) 0 1px, transparent 1px 19px);
|
||
/* --rb-line is chosen to give 3.1:1 at full strength; composited at .3 over the void
|
||
band it falls to 1.44:1, which on a dark table map is not a faint grid, it is no
|
||
grid. .45 measures 1.80:1 — present as texture, still quiet enough that the amber
|
||
lock is the only thing competing for attention. */
|
||
opacity: .45;
|
||
-webkit-mask: radial-gradient(circle, #000 32%, transparent 74%);
|
||
mask: radial-gradient(circle, #000 32%, transparent 74%);
|
||
}
|
||
|
||
/* THE LOCK — four corner brackets, eight solid background layers (two arms a corner).
|
||
`linear-gradient(colour 0 0)` is the shorthand for a flat colour layer; each is sized
|
||
to an arm and pinned to its corner, so the set scales as one piece. */
|
||
#pause.paused img {
|
||
--rb-lock-arm: 30px;
|
||
--rb-lock-line: 2px;
|
||
width: var(--rb-pause-field);
|
||
height: var(--rb-pause-field);
|
||
object-fit: none; object-position: -9999px -9999px;
|
||
border: none; box-shadow: none; filter: none;
|
||
background:
|
||
linear-gradient(var(--rb-yellow) 0 0) 0 0 / var(--rb-lock-line) var(--rb-lock-arm) no-repeat,
|
||
linear-gradient(var(--rb-yellow) 0 0) 0 0 / var(--rb-lock-arm) var(--rb-lock-line) no-repeat,
|
||
linear-gradient(var(--rb-yellow) 0 0) 100% 0 / var(--rb-lock-line) var(--rb-lock-arm) no-repeat,
|
||
linear-gradient(var(--rb-yellow) 0 0) 100% 0 / var(--rb-lock-arm) var(--rb-lock-line) no-repeat,
|
||
linear-gradient(var(--rb-yellow) 0 0) 0 100% / var(--rb-lock-line) var(--rb-lock-arm) no-repeat,
|
||
linear-gradient(var(--rb-yellow) 0 0) 0 100% / var(--rb-lock-arm) var(--rb-lock-line) no-repeat,
|
||
linear-gradient(var(--rb-yellow) 0 0) 100% 100% / var(--rb-lock-line) var(--rb-lock-arm) no-repeat,
|
||
linear-gradient(var(--rb-yellow) 0 0) 100% 100% / var(--rb-lock-arm) var(--rb-lock-line) no-repeat;
|
||
}
|
||
/* Core adds fa-spin to that img; ours must be the only animation running on it. One
|
||
declaration for both selectors so the two can never be given different timings. */
|
||
#pause.paused img,
|
||
#pause.paused img.fa-spin {
|
||
animation: rb-pause-lock var(--rb-pause-cycle) linear infinite;
|
||
}
|
||
|
||
/* THE SCAN — one line reading down the field. Bright in the middle and gone at the ends,
|
||
so it never collides with the brackets it passes. */
|
||
#pause.paused::after {
|
||
content: "";
|
||
position: absolute;
|
||
top: var(--rb-pause-top);
|
||
left: 50%;
|
||
margin-left: calc(var(--rb-pause-field) / -2);
|
||
width: var(--rb-pause-field);
|
||
height: 2px;
|
||
background: linear-gradient(to right,
|
||
transparent 0%,
|
||
var(--rb-yellow-dim) 20%,
|
||
var(--rb-yellow) 50%,
|
||
var(--rb-yellow-dim) 80%,
|
||
transparent 100%);
|
||
animation: rb-pause-scan calc(var(--rb-pause-cycle) / 3) linear infinite;
|
||
}
|
||
|
||
/* THE READOUT */
|
||
#pause.paused figcaption {
|
||
font-family: var(--rb-display);
|
||
font-size: 21px;
|
||
/* Michroma is already a wide face, and .4em on top of it set GAME PAUSED at 176px
|
||
against a 190px field — 93%, running bracket to bracket, so the readout fought the
|
||
lock for the same width. .22em measures 154px, 81%, which sits inside the brackets
|
||
and still reads as a tracked instrument label. */
|
||
letter-spacing: .22em;
|
||
/* letter-spacing adds its gap after the last glyph too; pull the line back by one to
|
||
keep the word optically centred under the field */
|
||
text-indent: .22em;
|
||
text-transform: uppercase;
|
||
color: var(--rb-yellow);
|
||
line-height: 1.2;
|
||
/* pinned, so --rb-pause-top stays correct even before the display face loads */
|
||
height: var(--rb-pause-readout);
|
||
text-shadow: 0 2px 18px var(--rb-void);
|
||
animation: rb-pause-readout var(--rb-pause-cycle) linear infinite;
|
||
}
|
||
|
||
/* Acquire on an S-curve that spends its time travelling and arrives late, so the closing
|
||
fills the acquire phase instead of finishing early and leaving the brackets sitting
|
||
still waiting for the readout. Hold flat, then ease-in out of the hold: a release
|
||
accelerates, it does not glide. */
|
||
@keyframes rb-pause-lock {
|
||
0% { transform: scale(1.14); opacity: .3; animation-timing-function: cubic-bezier(.6,.02,.3,1); }
|
||
22% { transform: scale(1); opacity: 1; }
|
||
70% { transform: scale(1); opacity: 1; animation-timing-function: ease-in; }
|
||
80% { transform: scale(1.06); opacity: .16; }
|
||
100% { transform: scale(1.14); opacity: .3; }
|
||
}
|
||
|
||
/* Fades in and out at the extremes so the line is never cut off mid-stroke at the edge
|
||
of the field it is reading. */
|
||
@keyframes rb-pause-scan {
|
||
0% { transform: translateY(0); opacity: 0; }
|
||
14% { opacity: .9; }
|
||
86% { opacity: .9; }
|
||
100% { transform: translateY(calc(var(--rb-pause-field) - 2px)); opacity: 0; }
|
||
}
|
||
|
||
/* Welded to the lock: up at 22%, down at 70%, and the 1% ramps are ~48ms, which reads as
|
||
a readout switching rather than a caption fading. */
|
||
@keyframes rb-pause-readout {
|
||
0%, 21% { opacity: .34; }
|
||
22%, 69% { opacity: 1; }
|
||
70%, 100% { opacity: .34; }
|
||
}
|
||
|
||
/* An instrument acquiring in the corner of the eye is exactly what this preference is
|
||
about. Keep the object, stop the movement — including core's own pulse on the whole
|
||
figure. Rest in the LOCKED state, which is the one frame of the cycle that reads as a
|
||
complete thought: brackets closed, readout lit, scan holding on the ring. */
|
||
@media (prefers-reduced-motion: reduce) {
|
||
#pause.paused,
|
||
#pause.paused img,
|
||
#pause.paused img.fa-spin,
|
||
#pause.paused::after,
|
||
#pause.paused figcaption { animation: none; }
|
||
#pause.paused img { transform: scale(1); opacity: 1; }
|
||
#pause.paused figcaption { opacity: 1; }
|
||
#pause.paused::after {
|
||
transform: translateY(calc(var(--rb-pause-field) / 2));
|
||
opacity: .9;
|
||
}
|
||
}
|
||
|
||
/* ============================================================
|
||
PANIC — the short track
|
||
============================================================
|
||
Deliberately NOT the same colour as Coherence. The two tracks run in opposite
|
||
directions on different timescales, and a table that reads one as the other will make
|
||
the wrong decision at the worst moment: Coherence is cool and yellow like the rest of
|
||
the department, Panic warms as it climbs and ends red.
|
||
============================================================ */
|
||
|
||
.rb-vital-panic .rb-big { color: var(--rb-white); }
|
||
.rb-panic-steady .rb-big, .rb-panic-steady .rb-cohband { color: var(--rb-muted); }
|
||
.rb-panic-rattled .rb-big, .rb-panic-rattled .rb-cohband { color: var(--rb-white); }
|
||
.rb-panic-shaken .rb-big, .rb-panic-shaken .rb-cohband { color: var(--rb-yellow); }
|
||
.rb-panic-losing .rb-big, .rb-panic-losing .rb-cohband { color: #ffb066; }
|
||
.rb-panic-overwhelmed .rb-big, .rb-panic-overwhelmed .rb-cohband { color: var(--rb-danger); }
|
||
.rb-panic-broken .rb-big, .rb-panic-broken .rb-cohband { color: var(--rb-danger); }
|
||
.rb-vital-panic.rb-panic-broken { border-color: var(--rb-danger); }
|
||
|
||
.rb-panic-pips { display: flex; gap: 5px; list-style: none; margin: 8px 0; padding: 0; }
|
||
.rb-panic-pip {
|
||
width: 20px; height: 8px;
|
||
background: transparent; border: 1px solid var(--rb-hairline);
|
||
}
|
||
.rb-panic-pip.on { background: var(--rb-danger); border-color: var(--rb-danger); }
|
||
|
||
.rb-panic-move { display: flex; align-items: baseline; gap: 8px; margin: 6px 0; }
|
||
.rb-panic-from, .rb-panic-to {
|
||
font-family: var(--rb-display); font-size: 20px; color: var(--rb-white);
|
||
}
|
||
.rb-panic-arrow { color: var(--rb-muted); }
|
||
.rb-panic-band {
|
||
font-family: var(--rb-body); font-size: 11px; font-weight: 700;
|
||
letter-spacing: .1em; text-transform: uppercase; color: var(--rb-yellow);
|
||
}
|
||
.rb-panic-reason { font-size: 13px; color: var(--rb-white); margin: 4px 0; }
|
||
.rb-panic-note { font-size: 12px; color: var(--rb-muted); margin: 2px 0 6px; }
|
||
.rb-panic-pen { font-size: 13px; font-weight: 700; color: var(--rb-danger); margin: 2px 0; }
|
||
.rb-panic-break {
|
||
font-family: var(--rb-body); font-size: 12px; font-weight: 700; letter-spacing: .08em;
|
||
color: var(--rb-void); background: var(--rb-danger);
|
||
padding: 5px 8px; margin: 6px 0 0;
|
||
}
|
||
|
||
/* A fumbled relief puts a point ON. The card must say which way it went, or it reads
|
||
as "Psychology" printed over a number that just rose, and the table reads that as a
|
||
bug rather than as the rule. */
|
||
.rb-panic-worse {
|
||
font-family: var(--rb-body); font-size: 11px; font-weight: 700; letter-spacing: .08em;
|
||
text-transform: uppercase; color: var(--rb-void); background: var(--rb-danger);
|
||
padding: 2px 6px; margin-right: 6px;
|
||
}
|
||
|
||
/* The GM's two mid-scene cards: what everyone is on, and the scene ending. */
|
||
.rb-party-table { width: 100%; border-collapse: collapse; font-size: 12px; }
|
||
.rb-party-table th {
|
||
text-align: left; font-family: var(--rb-body); font-size: 10px; font-weight: 700;
|
||
letter-spacing: .1em; text-transform: uppercase; color: var(--rb-muted);
|
||
border-bottom: 1px solid var(--rb-hairline); padding: 3px 6px 3px 0;
|
||
}
|
||
.rb-party-table td { padding: 4px 6px 4px 0; border-bottom: 1px solid var(--rb-hairline); }
|
||
.rb-party-name { color: var(--rb-white); font-weight: 700; }
|
||
.rb-party-hurt { color: var(--rb-danger); }
|
||
.rb-party-w { font-weight: 700; color: var(--rb-danger); }
|
||
.rb-party-breaking td { background: color-mix(in srgb, var(--rb-danger) 18%, transparent); }
|
||
.rb-party-table em { font-style: normal; color: var(--rb-danger); font-weight: 700; }
|
||
.rb-scene-list { list-style: none; margin: 6px 0; padding: 0; }
|
||
.rb-scene-list li { display: flex; justify-content: space-between; padding: 2px 0; font-size: 13px; }
|
||
.rb-scene-name { color: var(--rb-white); }
|
||
.rb-scene-drop { color: var(--rb-yellow); font-variant-numeric: tabular-nums; }
|
||
|
||
/* Development — the button only exists while the GM has the phase open. */
|
||
.rb-cbtn-dev {
|
||
color: var(--rb-void); background: var(--rb-yellow); border-color: var(--rb-yellow);
|
||
}
|
||
.rb-cbtn-dev:hover { background: var(--rb-white); border-color: var(--rb-white); }
|
||
.rb-dev-count {
|
||
font-family: var(--rb-body); font-size: 11px; font-weight: 700; letter-spacing: .06em;
|
||
text-transform: uppercase; color: var(--rb-danger);
|
||
}
|
||
.rb-dev-open { color: var(--rb-yellow); font-size: 13px; margin: 4px 0; }
|
||
|
||
/* --- NPC anatomy -------------------------------------------------------------
|
||
The NPC sheet carried no hit locations at all while every NPC in the game had
|
||
them derived, armoured and wired to consequences. The figure and the table sit
|
||
side by side on the combat tab: the drawing for a glance, the numbers to edit. */
|
||
.rb-npc-anatomy {
|
||
display: grid;
|
||
grid-template-columns: minmax(0, 140px) minmax(0, 1fr);
|
||
gap: 12px;
|
||
align-items: start;
|
||
margin-bottom: 16px;
|
||
}
|
||
.rb-npc-figure { display: flex; justify-content: center; }
|
||
.rb-npc-figure .rb-body-svg { width: 100%; height: auto; max-height: 190px; }
|
||
.rb-npc-anatomy .rb-loctable { width: 100%; }
|
||
.rb-npc-anatomy .rb-loc-taken { width: 3.2em; text-align: right; }
|
||
|
||
/* The body-plan selector in the NPC header, beside natural armour. The select itself
|
||
reuses .rb-species-select from the character sheet — one control, one look. */
|
||
.rb-species { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
|
||
.rb-species .rb-species-select { width: 100%; max-width: 12em; margin-left: 0; }
|
||
|
||
/* A flyer that has lost a wing has lost the fight it was going to have. */
|
||
.rb-flag-bad {
|
||
color: var(--rb-danger);
|
||
font-weight: 600;
|
||
letter-spacing: 0.02em;
|
||
}
|
||
.rb-cond-dying, .rb-cond-dead { color: var(--rb-danger); font-weight: 700; }
|
||
|
||
/* Damage rolled with nobody targeted. Quiet, but not silent. */
|
||
.rb-noloc { opacity: 0.8; font-style: italic; }
|
||
|
||
@media (max-width: 620px) {
|
||
.rb-npc-anatomy { grid-template-columns: minmax(0, 1fr); }
|
||
}
|