Files
RingBRP/styles/ringbrp.css
T
slaguru666andClaude Opus 5 5aaae186e0 A fumbled relief attempt puts a point on
Trying to steady somebody and making it worse is the most familiar thing on that
list, and until now it was the only outcome that cost nothing.

Done as a NEGATIVE relief rather than a second code path: panicReliefFor returns
-1 on a fumble, and easePanic already subtracts what it is given, so subtracting
a negative raises the track. One number, one direction, no branch that could
drift from the other. The clamp still holds — fumbling at 5 stays at 5.

The chat card had to be told, because otherwise it prints the word "Psychology"
over a number that has just gone UP and the table reads that as a bug rather than
as the rule. It now leads with a red FUMBLED tag.

Guarded three ways: a spot-check in check-rules for the -1 itself, and two
behaviour tests — one that the sign survives easePanic's subtraction and
actually raises the track, one that it cannot push past the top. A test on the
constant alone would have passed even if easePanic had healed on a fumble.

Verified live: 2 → fumble → 3 → success → 2 → special → 0, and a fumble at 5
staying at 5, with the cards reading correctly.

Version 1.1.2.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 23:25:46 +01:00

1843 lines
84 KiB
CSS
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* ============================================================
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-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-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-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 — a uniselector, stepping
============================================================
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 }`. The first version of this styled the bare #pause with display:flex and so
overrode the hide — the panel never went away when the game unpaused. EVERY rule here
that could affect visibility or layout is therefore scoped to `.paused`, and `display`
is not set anywhere.
Core also already centres it: a full-width band, 180px tall, at top calc(50vh - 100px),
column flex, centred both ways, pointer-events none. That layout is correct and is
left alone — only its size and its looks change here. The first version repositioned
it with left/bottom and pushed it off centre for the trouble.
A uniselector is the stepping switch inside a telephone exchange: an arm that clicks
round one contact at a time, hunting for a free line. The department's whole business
is a machine that says where things belong, and OPEN DAY is set inside one. Eleven
contacts, because eleven minutes is the interval this setting keeps returning to.
It STEPS rather than sweeps — a contact every 700ms. A continuous spin reads as a
loading throbber; a discrete click reads as a machine working through a list.
============================================================ */
/* Taller than core's 180px, and moved up by exactly half the extra so it stays centred. */
#pause.paused {
height: 300px;
top: calc(50vh - 150px);
gap: 28px;
background: linear-gradient(to right,
transparent 0%,
color-mix(in srgb, var(--rb-void) 82%, transparent) 38%,
color-mix(in srgb, var(--rb-void) 82%, transparent) 62%,
transparent 100%);
}
/* the dial: eleven contacts, standing still, behind the arm */
#pause.paused::before {
content: "";
position: absolute;
top: 24px; left: 50%; margin-left: -85px;
width: 170px; height: 170px;
border-radius: 50%;
background:
repeating-conic-gradient(from -90deg,
var(--rb-line) 0deg 1.6deg, transparent 1.6deg 32.727deg);
-webkit-mask: radial-gradient(circle, transparent 0 52px, #000 54px);
mask: radial-gradient(circle, transparent 0 52px, #000 54px);
opacity: .9;
}
/* the arm. 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. */
#pause.paused img {
width: 170px; height: 170px;
object-fit: none; object-position: -9999px -9999px;
border: none; box-shadow: none; filter: none;
/* the arm, and behind it the contact it has just left — without the trailing sector
a 700ms step is easy to miss, and the stepping is the whole idea */
background: conic-gradient(from -91deg,
var(--rb-yellow) 0deg 3.5deg,
var(--rb-yellow-dim) 3.5deg 28deg,
transparent 28deg 360deg);
-webkit-mask: radial-gradient(circle, #000 0 78px, transparent 80px);
mask: radial-gradient(circle, #000 0 78px, transparent 80px);
animation: rb-uniselector 7.7s steps(11, end) infinite;
}
/* core adds fa-spin to that img; ours must be the only rotation running */
#pause.paused img.fa-spin { animation: rb-uniselector 7.7s steps(11, end) infinite; }
/* the hub, and the amber that says the record is being written */
#pause.paused::after {
content: "";
position: absolute;
top: 101px; left: 50%; margin-left: -8px;
width: 16px; height: 16px;
border-radius: 50%;
background: var(--rb-yellow);
animation: rb-pause-pip 2.6s ease-in-out infinite;
}
#pause.paused figcaption {
font-family: var(--rb-display);
font-size: 24px;
letter-spacing: .3em;
text-transform: uppercase;
color: var(--rb-yellow);
line-height: 1.2;
text-shadow: 0 2px 18px var(--rb-void);
}
@keyframes rb-uniselector { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }
@keyframes rb-pause-pip { 0%, 100% { opacity: .25; } 50% { opacity: 1; } }
/* A stepping dial 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. */
@media (prefers-reduced-motion: reduce) {
#pause.paused,
#pause.paused img,
#pause.paused img.fa-spin,
#pause.paused::after { animation: none; }
#pause.paused img { transform: rotate(-32.7deg); }
}
/* ============================================================
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;
}